0

我正在通过对话流、谷歌日历和 voximplant 开发语音助手。我需要管理多个日历,并根据一系列优先级选择首先在哪个日历上插入事件:例如,如果我有 4 个日历,我想检查第一个日历,如果后者没有。空间第二个日历被检查等等。我很难处理异步承诺和函数。有人知道如何帮我一把吗?

我将在下面发布代码:

// See https://github.com/dialogflow/dialogflow-fulfillment-nodejs
// for Dialogflow fulfillment library docs, samples, and to report issues
'use strict';

const parsePhoneNumber = require('libphonenumber-js/max');
const functions = require('firebase-functions');

const {
    google
} = require('googleapis');
const {
    WebhookClient
} = require('dialogflow-fulfillment');

// Enter your calendar ID below and service account JSON below
// The user has to insert his personal <'calendarId'>
const calendarId = ['xxxxxxxxxxxxxx@group.calendar.google.com', 'xxxxxxxxxxxxxxx@group.calendar.google.com', 'xxxxxxxxxxxxxx@group.calendar.google.com', 'xxxxxxxxxxxxxx@group.calendar.google.com'];
const serviceAccount = {
    "type": "service_account",
    "project_id": "",
    "private_key_id": "",
    "private_key": "-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----\n",
    "client_email": "",
    "client_id": "",
    "auth_uri": "https://accounts.google.com/o/oauth2/auth",
    "token_uri": "https://oauth2.googleapis.com/token",
    "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
    "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/scheduler%40italians-do-it-better.iam.gserviceaccount.com"
};

//Authentication in google calendar
const serviceAccountAuth = new google.auth.JWT({
    email: serviceAccount.client_email,
    key: serviceAccount.private_key,
    scopes: 'https://www.googleapis.com/auth/calendar'
});

const calendar = google.calendar('v3');
process.env.DEBUG = 'dialogflow:*'; // enables lib debugging statements

//time zone and time zone setting. 
//This parameter can be overridden by the user
const timeZone = 'Europe/Kaliningrad';
const timeZoneOffset = '+02:00';

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


    const agent = new WebhookClient({
        request,
        response
    });
    console.log("Parameters", agent.parameters);

    //Insert your <'company name'> here
    var company = "Deedy";
    const appointment_type = company + ' and ' + agent.parameters.name;

    //Make appointment function
    function makeAppointment(agent) {
        console.log("Parameters", agent.parameters.date);

        //Variable acquisition
        //const guests = agent.parameters.guests;  //paremetro in più
        //const email = agent.parameters.email; //parametro in più
        const phonenumber = agent.parameters.phonenumber;
        var phone = phonenumber.toString().length;
        let name = agent.parameters.name;

        //Declaration of the duration of the event. 
        //By default it is 1 hour from the start of the event. 
        //It can be modified by the customer
        const eventDuration = 1; //hours, so if you want an event of a day duration you have to write "24"
        // Calculate appointment start and end datetimes (end = +1hr from start)
        const dateTimeStart = new Date(Date.parse(agent.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() + eventDuration));
        console.log("date start ", dateTimeStart, " date end ", dateTimeEnd);

        const date = new Date(agent.parameters.date);
        const bookingDate = new Date(date);
        const now = new Date();
        const appointmentTimeString = dateTimeStart.toLocaleString('en-US', {
            timeZone: 'Europe/Kaliningrad',
            year: 'numeric',
            month: 'numeric',
            day: 'numeric',
            hour: '2-digit',
            minute: '2-digit'
        });

        //Checks
        /*if (guests < 1) {
            agent.add(`You need to reserve a table for at least one person. Please try remaking the reservation!`);
        //} else if (guests > 100) {
            agent.add(`You can't make a reservation for more than 100 guests. Please try remaking the reservation!`);
        } else*/
        if (dateTimeStart < now) {
            agent.add(`You can't make a reservation in the past. Please try remaking the reservation.`);
        } else if (bookingDate.getFullYear() > now.getFullYear()) {
            agent.add(`You can't make a reservation for ${bookingDate.getFullYear()} yet. Please choose a date in ${now.getFullYear()}.`);
        } else if (phone < 10) {
            agent.add(`Your phone number has to be atleast 10 digits. Please try remaking the reservation!`);
        } else if (phone > 15) {
            agent.add(`Your phone number is too long. Please try remaking the reservation!`);
        } else {
            console.log("appointmentTimeString: ", appointmentTimeString);
            // Check the availibility of the time, and make an appointment if there is time on the calendar
            return createCalendarEvent(dateTimeStart, dateTimeEnd, name, phonenumber, appointment_type).then(() => {
                agent.add(`Ok, let me see if we can fit you in. ${appointmentTimeString} is fine!.`);
            }).catch(() => {
                agent.add(`I'm sorry, there are no slots available for ${appointmentTimeString}.`);
            });
        }
    }

    //Make the webhook calls
    let intentMap = new Map();

    intentMap.set('ScheduleAppointment.yes', makeAppointment);

    agent.handleRequest(intentMap);
});

function createCalendarEvent(dateTimeStart, dateTimeEnd, name, phonenumber, appointment_type) {
    const appointmentTimeString = dateTimeStart.toLocaleString('en-US', {
        timeZone: 'Europe/Kaliningrad',
        year: 'numeric',
        month: 'numeric',
        day: 'numeric',
        hour: '2-digit',
        minute: '2-digit'
    });
    return new Promise((resolve, reject) => {
for(let i=0;i<calendarId.length;i++){
            calendar.events.list({
                auth: serviceAccountAuth, // List events for time period
                calendarId: calendarId[i],
                timeMin: dateTimeStart.toISOString(),
                timeMax: dateTimeEnd.toISOString()
            }, (err, calendarResponse) => {
                // Check if there is a event already on the Calendar
                if (err || calendarResponse.data.items.length > 0) {
                    reject(err || new Error('Requested time conflicts with another appointment'));
                } else {
                    // Create event for the requested time period
                  //let fatto=true;
                    calendar.events.insert({
                     
                        auth: serviceAccountAuth,
                        calendarId: calendarId[i],
                        resource: {
                            summary: 'Appointment: ' + appointment_type,
                            description: "Date and time: " + appointmentTimeString + ',\n Name: ' + name + ',\n Phone number: ' + phonenumber,
                            start: {
                                dateTime: dateTimeStart
                            },
                            end: {
                                dateTime: dateTimeEnd
                            }
                        }
                    },(err, event) => {
                    err ? reject(event) : resolve(event);
                });
                }
            });
        }
    });
}

包.json:

{
  "name": "dialogflowFirebaseFulfillment",
  "description": "This is the default fulfillment for a Dialogflow agents using Cloud Functions for Firebase",
  "version": "0.0.1",
  "private": true,
  "license": "Apache Version 2.0",
  "author": "Google Inc.",
  "engines": {
    "node": "10"
  },
  "scripts": {
    "start": "firebase serve --only functions:dialogflowFirebaseFulfillment",
    "deploy": "firebase deploy --only functions:dialogflowFirebaseFulfillment"
  },
  "dependencies": {
    "actions-on-google": "^2.2.0",
    "firebase-admin": "^5.13.1",
    "firebase-functions": "^2.0.2",
    "dialogflow": "^0.6.0",
    "dialogflow-fulfillment": "^0.6.1",
    "nodemailer": "6.6.3",
    "libphonenumber-js": "1.9.23"
  }
}
4

0 回答 0