#google-apps-script #google-calendar-api #dialogflow-es
# #google-apps-script #google-calendar-api #dialogflow-es
Вопрос:
Я работаю над проектом чат-бота, используя Dialogflow API, Apps Script, Calendar API. Чат-бот должен иметь возможность организовать встречу между двумя или более участниками прямо из чата. Например, пользователь говорит что-то вроде «организуйте встречу с john.smith@mail.com на завтра в 5 часов вечера», и чат-бот должен перейти к обоим календарям — моему и Джона, проверить наличие свободных мест на этот период времени и забронировать встречу. Пока все хорошо. У меня уже есть решение для этого этапа (проверьте фрагмент кода ниже). Мой вопрос в том, заняты ли пользователи в течение этого периода времени, как я могу получить предлагаемое время, когда все участники свободны. Я использую свободный / занятый звонок, но он возвращается только тогда, когда пользователи заняты.
//the function search in spreadshet containing all timezones and selects the corresponding offset
function setCorrectTimeZone(rawTime,rawDate){
var spreadSheet = SpreadsheetApp.openById("10tJCi5bRHs3Cl8Gvw8NGMeHhfRBDnvPD338peH2MWyg"); //the timezones sheed ID stored in CEE Google Assistant shared drive
var sheet = spreadSheet.getSheetByName("timezones");
var timezoneRange = sheet.getRange(2, 1, 513, 2).getValues();
//getting the user's timezone
var userTimeZone = CalendarApp.getDefaultCalendar().getTimeZone();
Logger.log("User time zone: " userTimeZone);
var userTimeZoneOffset = "";
var correctDateTimeAndZone = "";
//iterating over the timezones from the sheet and comparing with user's to find the correct offset
for(var i = 0; i<timezoneRange.length; i ){
if(timezoneRange[i][1] == userTimeZone){
userTimeZoneOffset = timezoneRange[i][0];
}
}
//taking the date only
var date = rawDate.split('T')[0];
//taking the time only
var timeNoTimeZone = rawTime.split(' ')[0].split('T')[1];
//concatenating the date, time and the correct timezone together
correctDateTimeAndZone = date 'T' timeNoTimeZone userTimeZoneOffset;
return correctDateTimeAndZone;
}
function organizeMeeting(dialogflowRawResponse, email) {
var guestEmail = dialogflowRawResponse.queryResult.parameters.email; //the list of all guests
var rawDate = dialogflowRawResponse.queryResult.parameters.date;
var rawTime = dialogflowRawResponse.queryResult.parameters.time;
var eventTitle = dialogflowRawResponse.queryResult.parameters.meetingName;
var hasAllParams = dialogflowRawResponse.queryResult.hasOwnProperty('allRequiredParamsPresent'); //checker for all parameters
var correctedTimezone = setCorrectTimeZone(rawTime,rawDate);
Logger.log("Has all required parameters? " hasAllParams);
//check if all parameters are passed
while(hasAllParams == false){
Logger.log("Parameters are missing");
Logger.log(dialogflowRawResponse.queryResult.fulfillmentText);
return { text: dialogflowRawResponse.queryResult.fulfillmentText };
}
Logger.log("Guests email list detected: " JSON.stringify(guestEmail) "nDate-time detected: " rawTime "nCorrect date-time timezone: " correctedTimezone "nTitle detected: " eventTitle);
//setting the date-time for the start and the end of the event
var dateTimeStart = new Date(correctedTimezone);
var dateTimeEnd = new Date(correctedTimezone);
dateTimeEnd.setHours(dateTimeEnd.getHours() 1);
dateTimeStart = dateTimeStart.toISOString();
dateTimeEnd = dateTimeEnd.toISOString();
Logger.log("ISO dateTimeStart: " dateTimeStart);
Logger.log("ISO dateTimeEnd: " dateTimeEnd);
var participants = [{"id": email}]; //array of objects. Each object is a particpant for the event
for(var i = 0; i < guestEmail.length; i ){
participants.push({"id": guestEmail[i]}); //filling the participant array
}
//preparing the body for the Calendar API free-busy request
var requestBody = {
"timeMin": dateTimeStart,
"timeMax": dateTimeEnd,
"items": participants
}
//Calendar freebusy request to check if the slot is available for all particiaptns
var response = Calendar.Freebusy.query(requestBody);
for(var i = 0; i < participants.length; i ){
var calendarId = participants[i].id;
if(response.calendars[calendarId]['busy'].length != 0){
Logger.log(calendarId " is busy at this time");
return { text: calendarId " is busy at this time" };
break;
}
}
//guest array of objects for each participant
var guestsArr = [{"email":email}];
for(var i = 0; i < guestEmail.length; i ){
guestsArr.push({"email": guestEmail[i]});
}
//preparing the event details for the Calendar API call
var event = {
"summary": eventTitle,
"end": {
"dateTime": dateTimeEnd
},
"start": {
"dateTime": dateTimeStart
},
"attendees": guestsArr
}
//preapring the event options for the Calendar API call
var eventOptions = {
"sendNotifications": true,
"sendUpdates": "all"
}
//Calendar API call
var calendarEventRequest = Calendar.Events.insert(event, "primary",eventOptions);
//logs the Calendar API response to the logs
Logger.log(JSON.stringify(calendarEventRequest));
return { text: "Done! Check you calendar." };
}
Приведенный выше код принимает параметры из API Dialogflow — дату, время, название собрания и участников и использует эту информацию для выполнения свободного / занятого вызова, а затем, в конечном итоге, вызова API календаря. Он также использует базу данных электронных таблиц для поиска правильного часового пояса пользователя на основе местоположения пользователя.
Любая помощь будет высоко оценена, если кто-то уже использовал такую функцию, чтобы получить доступные временные интервалы.
Комментарии:
1. Я не думаю, что есть API для Google Calendar, чтобы получить свободное время, вам нужно будет вычислить это самостоятельно. Существует бесплатный API, который может быть полезен developers.google.com/calendar/v3/reference/freebusy/query
Ответ №1:
Вы можете проверить каждый часовой временной интервал, если все свободны, если все свободны, затем отправить приглашения в Календаре.
Пример кода:
var dateTimeStart = new Date(correctedTimezone);
var dateTimeEnd = new Date(correctedTimezone);
do {
dateTimeEnd.setHours(dateTimeStart.getHours() 1);
dateTimeStart = dateTimeStart.toISOString();
dateTimeEnd = dateTimeEnd.toISOString();
Logger.log("ISO dateTimeStart: " dateTimeStart);
Logger.log("ISO dateTimeEnd: " dateTimeEnd);
var participants = [{"id": email}]; //array of objects. Each object is a particpant for the event
for(var i = 0; i < guestEmail.length; i ){
participants.push({"id": guestEmail[i]}); //filling the participant array
}
//preparing the body for the Calendar API free-busy request
var requestBody = {
"timeMin": dateTimeStart,
"timeMax": dateTimeEnd,
"items": participants
}
//Calendar freebusy request to check if the slot is available for all particiaptns
var response = Calendar.Freebusy.query(requestBody);
for(var i = 0; i < participants.length; i ){
var calendarId = participants[i].id;
if(response.calendars[calendarId]['busy'].length != 0){
dateTimeStart.setHours(dateTimeStart.getHours() 1);
Logger.log(calendarId " is busy at this time");
//return { text: calendarId " is busy at this time" };
break;
}
}
}
while (response.calendars[calendarId]['busy'].length != 0);