Google Chat'ten toplantı planlama

Kodlama seviyesi: Orta
Süre: 25 dakika
Proje türü: Google Chat uygulaması

Hedefler

  • Çözümün ne işe yaradığını anlayın.
  • Apps Komut Dosyası hizmetlerinin çözümüne geçelim.
  • Ortamınızı ayarlayın.
  • Komut dosyasını ayarlayın.
  • Komut dosyasını çalıştırın.

Bu çözüm hakkında

Google Takvim'de doğrudan mesaj (DM) üzerinden veya alanına sahip olmanız gerekir. Toplantı için aşağıdakiler gibi belirli ayrıntıları ayarlayabilirsiniz: veya anlık video için varsayılan ayarları kullanın. toplantı planlamanıza yardımcı olur.

Toplantı Planlayıcı Sohbet uygulamasının iletişim kutusu arayüzü

İşleyiş şekli

Chat uygulaması komut dosyası eğik çizgi komutları ve iletişim kutuları ayrıntılı toplantı düzenlemelerine olanak tanır. İlgili içeriği oluşturmak için kullanılan komut dosyası, kendi ayarlarınıza uyacak şekilde özelleştirilebilen varsayılan toplantı ayarları gerekiyor.

Apps Komut Dosyası hizmetleri

Bu çözüm aşağıdaki hizmetleri kullanır:

  • Takvim hizmeti: takvim etkinliği eklenir.
  • Temel hizmet: Aşağıdakileri almak için Session sınıfını kullanır: komut dosyasının saat dilimini kullanır. Takvim aşağıdaki durumlarda bu saat dilimini kullanır: üzerine konuşacağız.
  • Yardımcı programlar hizmeti: Tarihi biçimlendirir. sağlar ve etkinlik URL'sinin alınmasına yardımcı olmak için etkinlik kimliğini kodlar.

Ön koşullar

Bu örneği kullanmak için aşağıdaki ön koşullara sahip olmanız gerekir:

  • Google Hesabı (Google Workspace hesapları (yönetici onayı gerektirir).
  • İnternete erişimi olan bir web tarayıcısı.
  • Bir Google Cloud projesi.

Ortamınızı ayarlama

Google Cloud Console'da Cloud projenizi açma

Açık değilse kullanmayı düşündüğünüz Cloud projesini açın şu örnekteki gibi:

  1. Google Cloud konsolunda Proje seçin sayfasına gidin.

    Cloud projesi seçin

  2. Kullanmak istediğiniz Google Cloud projesini seçin. İsterseniz Proje oluştur'u tıklayıp ekrandaki talimatları da uygulayabilirsiniz. Google Cloud projesi oluşturursanız proje için faturalandırmayı etkinleştirmeniz gerekebilir.

API'yi etkinleştirme

Google API'lerini kullanmadan önce bir Google Cloud projesinde etkinleştirmeniz gerekir. Tek bir Google Cloud projesinde bir veya daha fazla API'yi etkinleştirebilirsiniz.

Tüm Chat uygulamaları için izin ekranı yapılandırması gerekir. Yapılandırılıyor uygulamanızın OAuth izin ekranı, Google'ın kullanıcılara ve kullanıcılara daha sonra yayınlayabilmeniz için uygulamanızı kaydeder.

  1. Google Cloud konsolunda Menü'ye gidin > API'lar ve Hizmetler > OAuth izin ekranı.

    OAuth izin ekranına gidin.

  2. Kullanıcı türü için Dahili'yi seçin ve ardından Oluştur'u tıklayın.
  3. Uygulama kayıt formunu doldurup Kaydet ve Devam Et'i tıklayın.
  4. Şimdilik kapsam eklemeyi atlayıp Kaydet ve Devam Et'i tıklayabilirsiniz. Gelecekte Google Workspace kuruluşu kullanıyorsanız Kullanıcı türü'nü Harici olarak değiştirmeniz ve ardından Uygulamanızın gerektirdiği yetkilendirme kapsamlarını ekleyin.

  5. Uygulama kaydı özetinizi inceleyin. Değişiklik yapmak için Düzenle'yi tıklayın. Uygulama Kontrol Paneline Dön'ü tıklayın.

Komut dosyasını ayarlama

Apps Komut Dosyası projesini oluşturma

  1. Google Chat'ten toplantı planla bölümünü açmak için aşağıdaki düğmeyi tıklayın. Apps Komut Dosyası projesi.
    Projeyi açın
  2. Genel Bakış tıklayın.
  3. Genel bakış sayfasında Kopya oluştur'u Kopya oluşturma simgesi tıklayın.

Cloud projesi numarasını kopyalayın

  1. Google Cloud konsolunda Menü'ye gidin > IAM ve Yönetici > Ayarlar'a dokunun.

    IAM ve Yönetici Ayarları

  2. Proje numarası alanına değeri kopyalayın.

Apps Komut Dosyası projesinin Cloud projesini ayarlayın

  1. Kopyaladığınız Apps Komut Dosyası projenizde, Proje Ayarları'nı Proje ayarları simgesi tıklayın.
  2. Google Cloud Platform (GCP) Project bölümünde Projeyi değiştir seçeneğini tıklayın.
  3. GCP proje numarası alanına Google Cloud proje numarasını yapıştırın.
  4. Proje ayarla'yı tıklayın.

Test dağıtımı oluşturma

  1. Kopyaladığınız Apps Komut Dosyası projenizde Dağıt'ı tıklayın. > Dağıtımları test edin.
  2. Sonraki adımda kullanmak üzere Head dağıtım kimliğini kopyalayın ve Bitti'yi tıklayın.

Chat API'yi yapılandırma

  1. Google Cloud konsolunda Chat API sayfasına gidin.
    Chat API'ye gidin
  2. Yapılandırma'yı tıklayın.
  3. Chat API'yi aşağıdaki bilgilerle yapılandırın:
    • Ad: Meeting Scheduler
    • Avatar URL'si: Minimum boyuttaki bir resme yönlendiren bir URL ekleyin: 256x256 piksel.
    • Açıklama: Quickly create meetings.
    • İşlevsellik: Kullanıcıların uygulamaya doğrudan mesaj göndermesine izin vermek için her iki kutuyu da işaretleyin ve alanlara ekleyin.
    • Bağlantı ayarları: Apps Komut Dosyası'nı tıklayın ve ana dağıtım kimliği.
    • Eğik çizgi komutları: /help ve /schedule_Meeting için eğik çizgi komutları ekleyin. şu adımları uygulayarak:
      1. Eğik çizgi komutu ekle'yi tıklayın ve aşağıdaki şekilde yapılandırın. bilgi:
        • Ad: /help
        • Komut Kimliği: 1
        • Açıklama: Learn what this app does.
      2. Eğik çizgi komutu ekle'yi tekrar tıklayın ve aşağıdaki şekilde yapılandırın. bilgi:
        • Ad: /schedule_Meeting
        • Komut Kimliği: 2
        • Açıklama: Schedule a meeting.
        • Bir iletişim kutusu açar kutusunu işaretleyin.
    • İzinler: Alanınızdaki belirli kişiler ve gruplar'ı seçin ve e-posta adresinizi girin.
  4. Kaydet'i tıklayın ve sayfayı yenileyin.
  5. Yapılandırma sayfasındaki Uygulama durumu bölümünde uygulamanın durumunu Canlı - kullanıcılara açık olarak değiştirin.
  6. Kaydet'i tıklayın.

Komut dosyasını çalıştırma

  1. Google Chat'i açın.
  2. Sohbet başlat'ı tıklayın.
  3. Uygulamanın adını (Meeting Scheduler) arayın.
  4. Yetkilendirme istemek için hello gibi bir ilk mesaj gönderin.
  5. Uygulama yanıt verdiğinde Yapılandır'ı tıklayın ve uygulamayı yetkilendirin. OAuth izin ekranında Bu uygulama doğrulanmadı uyarısı gösteriliyorsa Gelişmiş'i > seçerek devam edin {Project Name} projesine (güvenli değil) gidin.

  6. /schedule_Meeting öğesini uygulamaya gönderin.

  7. İletişim kutusunda en az bir davetli e-posta adresi ekleyin. Araç Çubuğu’nun veya varsayılan girişleri kullanın.

  8. Gönder'i tıklayın.

  9. Toplantıyı görüntülemek için Takvim etkinliğini aç'ı tıklayın.

Kodu inceleyin

Bu çözüm için Apps Komut Dosyası kodunu incelemek üzere Aşağıdaki kaynak kodu görüntüleyin:

Kaynak kodu göster

Code.gs

solutions/schedule-meetings/Code.js
// To learn how to use this script, refer to the documentation:
// https://developers.google.com/apps-script/samples/chat-apps/schedule-meetings

/*
Copyright 2022 Google LLC

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

// Application constants
const APPNAME = 'Chat Meeting Scheduler';
const SLASHCOMMAND = {
  HELP: 1, // /help
  DIALOG: 2, // /schedule_Meeting
};

/**
 * Responds to an ADDED_TO_SPACE event in Google Chat.
 * Called when the Chat app is added to a space. The Chat app can either be directly added to the space
 * or added by a @mention. If the Chat app is added by a @mention, the event object includes a message property. 
 * Returns a Message object, which is usually a welcome message informing users about the Chat app.
 *
 * @param {Object} event The event object from Google Chat
 */
function onAddToSpace(event) {
  let message = '';

  // Personalizes the message depending on how the Chat app is called.
  if (event.space.singleUserBotDm) {
    message = `Hi ${event.user.displayName}!`;
  } else {
    const spaceName = event.space.displayName ? event.space.displayName : "this chat";
    message = `Hi! Thank you for adding me to ${spaceName}`;
  }

  // Lets users know what they can do and how they can get help.
  message = message + '/nI can quickly schedule a meeting for you with just a few clicks.' +
    'Try me out by typing */schedule_Meeting*. ' +
    '/nTo learn what else I can do, type */help*.'

  return { "text": message };
}

/**
 * Responds to a MESSAGE event triggered in Chat.
 * Called when the Chat app is already in the space and the user invokes it via @mention or / command.
 * Returns a message object containing the Chat app's response. For this Chat app, the response is either the
 * help text or the dialog to schedule a meeting.
 * 
 * @param {object} event The event object from Google Chat
 * @return {object} JSON-formatted response as text or Card message
 */
function onMessage(event) {

  // Handles regular onMessage logic.
  // Evaluates if and handles for all slash commands.
  if (event.message.slashCommand) {
    switch (event.message.slashCommand.commandId) {

      case SLASHCOMMAND.DIALOG: // Displays meeting dialog for /schedule_Meeting.

        // TODO update this with your own logic to set meeting recipients, subjects, etc (e.g. a group email).
        return getInputFormAsDialog_({
          invitee: '',
          startTime: getTopOfHourDateString_(),
          duration: 30,
          subject: 'Status Stand-up',
          body: 'Scheduling a quick status stand-up meeting.'
        });

      case SLASHCOMMAND.HELP: // Responds with help text for /help.
        return getHelpTextResponse_();

      /* TODO Add other use cases here. E.g:
      case SLASHCOMMAND.NEW_FEATURE:  // Your Feature Here
        getDialogForAddContact(message);
      */

    }
  }
  else {
    // Returns text if users didn't invoke a slash command.
    return { text: 'No action taken - use Slash Commands.' }
  }
}

/**
 * Responds to a CARD_CLICKED event triggered in Chat.
 * @param {object} event the event object from Chat
 * @return {object} JSON-formatted response
 * @see https://developers.google.com/chat/api/guides/message-formats/events
 */
function onCardClick(event) {
  if (event.action.actionMethodName === 'handleFormSubmit') {
    const recipients = getFieldValue_(event.common.formInputs, 'email');
    const subject = getFieldValue_(event.common.formInputs, 'subject');
    const body = getFieldValue_(event.common.formInputs, 'body');

    // Assumes dialog card inputs for date and times are in the correct format. mm/dd/yyy HH:MM
    const dateTimeInput = getFieldValue_(event.common.formInputs, 'date');
    const startTime = getStartTimeAsDateObject_(dateTimeInput);
    const duration = Number(getFieldValue_(event.common.formInputs, 'duration'));

    // Handles instances of missing or invalid input parameters.
    const errors = [];

    if (!recipients) {
      errors.push('Missing or invalid recipient email address.');
    }
    if (!subject) {
      errors.push('Missing subject line.');
    }
    if (!body) {
      errors.push('Missing event description.');
    }
    if (!startTime) {
      errors.push('Missing or invalid start time.');
    }
    if (!duration || isNaN(duration)) {
      errors.push('Missing or invalid duration');
    }
    if (errors.length) {
      // Redisplays the form if missing or invalid inputs exist.
      return getInputFormAsDialog_({
        errors,
        invitee: recipients,
        startTime: dateTimeInput,
        duration,
        subject,
        body
      });
    }

    //  Calculates the end time via duration.
    const endTime = new Date(startTime.valueOf());
    endTime.setMinutes(endTime.getMinutes() + duration);

    // Creates calendar event with notification.
    const calendar = CalendarApp.getDefaultCalendar()
    const scheduledEvent = calendar.createEvent(subject,
      startTime,
      endTime,
      {
        guests: recipients,
        sendInvites: true,
        description: body + '\nThis meeting scheduled by a Google Chat App!'
      });

    // Gets a link to the Calendar event.
    const url = getCalendarEventURL_(scheduledEvent, calendar)

    return getConfirmationDialog_(url);

  } else if (event.action.actionMethodName === 'closeDialog') {

    // Returns this dialog as success.
    return {
      actionResponse: {
        type: 'DIALOG',
        dialog_action: {
          actionStatus: 'OK'
        }
      }
    }
  }
}

/**
 * Responds with help text about this Chat app.
 * @return {string} The help text as seen below
 */
function getHelpTextResponse_() {
  const help = `*${APPNAME}* lets you quickly create meetings from Google Chat. Here\'s a list of all its commands:
  \`/schedule_Meeting\`  Opens a dialog with editable, preset parameters to create a meeting event
  \`/help\`  Displays this help message

  Learn more about creating Google Chat apps at https://developers.google.com/chat.`

  return { 'text': help }
}

Dialog.gs

solutions/schedule-meetings/Dialog.js
/**
 * Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
* Form input dialog as JSON.
* @return {object} JSON-formatted cards for the dialog.
*/
function getInputFormAsDialog_(options) {
  const form = getForm_(options);
  return {
    'actionResponse': {
      'type': 'DIALOG',
      'dialogAction': {
        'dialog': {
          'body': form
        }
      }
    }
  };
}

/**
* Form JSON to collect inputs regarding the meeting.
* @return {object} JSON-formatted cards.
*/
function getForm_(options) {
  const sections = [];

  // If errors present, display additional section with validation messages.
  if (options.errors && options.errors.length) {
    let errors = options.errors.reduce((str, err) => `${str}• ${err}<br>`, '');
    errors = `<b>Errors:</b><br><font color="#ba0000">${errors}</font>`;
    const errorSection = {
      'widgets': [
        {
          textParagraph: {
            text: errors
          }
        }
      ]
    }
    sections.push(errorSection);
  }
  let formSection = {
    'header': 'Schedule meeting and send email to invited participants',
    'widgets': [
      {
        'textInput': {
          'label': 'Event Title',
          'type': 'SINGLE_LINE',
          'name': 'subject',
          'value': options.subject
        }
      },
      {
        'textInput': {
          'label': 'Invitee Email Address',
          'type': 'SINGLE_LINE',
          'name': 'email',
          'value': options.invitee,
          'hintText': 'Add team group email'
        }
      },
      {
        'textInput': {
          'label': 'Description',
          'type': 'MULTIPLE_LINE',
          'name': 'body',
          'value': options.body
        }
      },
      {
        'textInput': {
          'label': 'Meeting start date & time',
          'type': 'SINGLE_LINE',
          'name': 'date',
          'value': options.startTime,
          'hintText': 'mm/dd/yyyy H:MM'
        }
      },
      {
        'selectionInput': {
          'type': 'DROPDOWN',
          'label': 'Meeting Duration',
          'name': 'duration',
          'items': [
            {
              'text': '15 minutes',
              'value': '15',
              'selected': options.duration === 15
            },
            {
              'text': '30 minutes',
              'value': '30',
              'selected': options.duration === 30
            },
            {
              'text': '45 minutes',
              'value': '45',
              'selected': options.duration === 45
            },
            {
              'text': '1 Hour',
              'value': '60',
              'selected': options.duration === 60
            },
            {
              'text': '1.5 Hours',
              'value': '90',
              'selected': options.duration === 90
            },
            {
              'text': '2 Hours',
              'value': '120',
              'selected': options.duration === 120
            }
          ]
        }
      }
    ],
    'collapsible': false
  };
  sections.push(formSection);
  const card =  {
    'sections': sections,
    'name': 'Google Chat Scheduled Meeting',
    'fixedFooter': {
      'primaryButton': {
        'text': 'Submit',
        'onClick': {
          'action': {
            'function': 'handleFormSubmit'
          }
        },
        'altText': 'Submit'
      }
    }
  };
  return card;
}

/**
* Confirmation dialog after a calendar event is created successfully.
* @param {string} url The Google Calendar Event url for link button
* @return {object} JSON-formatted cards for the dialog
*/
function getConfirmationDialog_(url) {
  return {
    'actionResponse': {
      'type': 'DIALOG',
      'dialogAction': {
        'dialog': {
          'body': {
            'sections': [
              {
                'widgets': [
                  {
                    'textParagraph': {
                      'text': 'Meeting created successfully!'
                    },
                    'horizontalAlignment': 'CENTER'
                  },
                  {
                    'buttonList': {
                      'buttons': [
                        {
                          'text': 'Open Calendar Event',
                          'onClick': {
                            'openLink': {
                              'url': url
                            }
                          }
                        }

                      ]
                    },
                    'horizontalAlignment': 'CENTER'
                  }
                ]
              }
            ],
            'fixedFooter': {
              'primaryButton': {
                'text': 'OK',
                'onClick': {
                  'action': {
                    'function': 'closeDialog'
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

Utilities.gs

solutions/schedule-meetings/Utilities.js
/**
 * Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
* Helper function that gets the field value from the given form input.
* @return {string} 
*/
function getFieldValue_(formInputs, fieldName) {
  return formInputs[fieldName][''].stringInputs.value[0];
}

// Regular expression to validate the date/time input.
const DATE_TIME_PATTERN = /\d{1,2}\/\d{1,2}\/\d{4}\s+\d{1,2}:\d\d/;

/**
* Casts date and time from string to Date object.
* @return {date} 
*/
function getStartTimeAsDateObject_(dateTimeStr) {
  if (!dateTimeStr || !dateTimeStr.match(DATE_TIME_PATTERN)) {
    return null;
  }

  const parts = dateTimeStr.split(' ');
  const [month, day, year] = parts[0].split('/').map(Number);
  const [hour, minute] = parts[1].split(':').map(Number);


  Session.getScriptTimeZone()

  return new Date(year, month - 1, day, hour, minute)
}

/** 
* Gets the current date and time for the upcoming top of the hour (e.g. 01/25/2022 18:00).
* @return {string} date/time in mm/dd/yyy HH:MM format needed for use by Calendar
*/
function getTopOfHourDateString_() {
  const date = new Date();
  date.setHours(date.getHours() + 1);
  date.setMinutes(0, 0, 0);
  // Adding the date as string might lead to an incorrect response due to time zone adjustments.
  return Utilities.formatDate(date, Session.getScriptTimeZone(), 'MM/dd/yyyy H:mm');
}


/** 
* Creates the URL for the Google Calendar event.
*
* @param {object} event The Google Calendar Event instance
* @param {object} cal The associated Google Calendar 
* @return {string} URL in the form of 'https://www.google.com/calendar/event?eid={event-id}'
*/
function getCalendarEventURL_(event, cal) {
  const baseCalUrl = 'https://www.google.com/calendar';
  // Joins Calendar Event Id with Calendar Id, then base64 encode to derive the event URL.
  let encodedId = Utilities.base64Encode(event.getId().split('@')[0] + " " + cal.getId()).replace(/\=/g, '');
  encodedId = `/event?eid=${encodedId}`;
  return (baseCalUrl + encodedId);

}

Katkıda bulunanlar

Bu örnek, Google Geliştirici Uzmanları'nın yardımıyla Google tarafından yönetilir.

Sonraki adımlar