Ważne: ten przewodnik po szybkim uruchomieniu jest przeznaczony tylko dla dostawców usług konferencji internetowych.
Ten przewodnik po dodatku do Google Workspace umożliwia rozszerzenie Kalendarza Google o synchronizację z fikcyjną usługą konferencji internetowej o nazwie Moja konferencja internetowa. Podczas edytowania wydarzeń w Kalendarzu dodatek pozwala użytkownikom zobaczyć Moje rozmowy wideo w internecie jako opcję rozmowy wideo.
Przykładowy scenariusz pokazuje tworzenie konferencji i synchronizację wydarzeń, ale nie działa, dopóki nie połączysz go z interfejsem API rozwiązania do rozmów wideo.
Cele
- skonfigurować środowisko,
- Skonfiguruj skrypt.
- Uruchom skrypt.
Wymagania wstępne
- przeglądarka internetowa z dostępem do internetu;
- Konto Google Workspace (może być potrzebna zgoda administratora).
- projekt Google Cloud,
Konfigurowanie środowiska
Otwieranie projektu Cloud w konsoli Google Cloud
Jeśli nie jest jeszcze otwarty, otwórz projekt Cloud, którego chcesz użyć w przypadku tej próbki:
- W konsoli Google Cloud otwórz stronę Wybierz projekt.
- Wybierz projekt Google Cloud, którego chcesz użyć. Możesz też kliknąć Utwórz projekt i postępować zgodnie z instrukcjami wyświetlanymi na ekranie. Jeśli tworzysz projekt Google Cloud, konieczne może być włączenie płatności.
Włącz interfejs Calendar API
W tym krótkim wprowadzeniu użyjemy zaawansowanej usługi Kalendarza, która uzyskuje dostęp do interfejsu Calendar API.
Zanim zaczniesz korzystać z interfejsów API Google, musisz je włączyć w projekcie Google Cloud. W jednym projekcie Google Cloud możesz włączyć 1 lub więcej interfejsów API.W projekcie Google Cloud włącz interfejs Calendar API.
Konfigurowanie ekranu zgody OAuth
Dodatki Google Workspace wymagają skonfigurowania ekranu z prośbą o zgodę. Konfiguracja ekranu zgody OAuth w Twoim dodatku Google Workspace określa, co Google wyświetla użytkownikom.
- W konsoli Google Cloud kliknij Menu > Interfejsy API i usługi > Ekran zgody OAuth.
- W polu Typ użytkownika wybierz Wewnętrzny, a następnie kliknij Utwórz.
- Wypełnij formularz rejestracji aplikacji, a potem kliknij Zapisz i kontynuuj.
Możesz pominąć dodawanie zakresów i kliknąć Zapisz i kontynuuj. Gdy w przyszłości będziesz tworzyć aplikację do użytku poza organizacją Google Workspace, musisz zmienić Typ użytkownika na Zewnętrzny, a następnie dodać zakresy autoryzacji wymagane przez aplikację.
- Sprawdź podsumowanie rejestracji aplikacji. Aby wprowadzić zmiany, kliknij Edytuj. Jeśli rejestracja aplikacji wygląda dobrze, kliknij Powrót do panelu.
Konfigurowanie skryptu
Tworzenie projektu Apps Script
- Aby utworzyć nowy projekt Apps Script, otwórz stronę script.new.
- Kliknij Projekt bez tytułu.
- Zmień nazwę projektu Apps Script na Wtyczka konferencji i kliknij Zmień nazwę.
- Obok pliku
Code.gs
kliknij Więcej > Zmień nazwę. Nazwij plik.CreateConf
- Kliknij Dodaj plik > Skrypt.
- Nazwij plik
Syncing
. Zamień zawartość każdego pliku na odpowiedni kod:
CreateConf.gs
/** * Creates a conference, then builds and returns a ConferenceData object * with the corresponding conference information. This method is called * when a user selects a conference solution defined by the add-on that * uses this function as its 'onCreateFunction' in the add-on manifest. * * @param {Object} arg The default argument passed to a 'onCreateFunction'; * it carries information about the Google Calendar event. * @return {ConferenceData} */ function createConference(arg) { const eventData = arg.eventData; const calendarId = eventData.calendarId; const eventId = eventData.eventId; // Retrieve the Calendar event information using the Calendar // Advanced service. var calendarEvent; try { calendarEvent = Calendar.Events.get(calendarId, eventId); } catch (err) { // The calendar event does not exist just yet; just proceed with the // given event ID and allow the event details to sync later. console.log(err); calendarEvent = { id: eventId, }; } // Create a conference on the third-party service and return the // conference data or errors in a custom JSON object. var conferenceInfo = create3rdPartyConference(calendarEvent); // Build and return a ConferenceData object, either with conference or // error information. var dataBuilder = ConferenceDataService.newConferenceDataBuilder(); if (!conferenceInfo.error) { // No error, so build the ConferenceData object from the // returned conference info. var phoneEntryPoint = ConferenceDataService.newEntryPoint() .setEntryPointType(ConferenceDataService.EntryPointType.PHONE) .setUri('tel:+' + conferenceInfo.phoneNumber) .setPin(conferenceInfo.phonePin); var adminEmailParameter = ConferenceDataService.newConferenceParameter() .setKey('adminEmail') .setValue(conferenceInfo.adminEmail); dataBuilder.setConferenceId(conferenceInfo.id) .addEntryPoint(phoneEntryPoint) .addConferenceParameter(adminEmailParameter) .setNotes(conferenceInfo.conferenceLegalNotice); if (conferenceInfo.videoUri) { var videoEntryPoint = ConferenceDataService.newEntryPoint() .setEntryPointType(ConferenceDataService.EntryPointType.VIDEO) .setUri(conferenceInfo.videoUri) .setPasscode(conferenceInfo.videoPasscode); dataBuilder.addEntryPoint(videoEntryPoint); } // Since the conference creation request succeeded, make sure that // syncing has been enabled. initializeSyncing(calendarId, eventId, conferenceInfo.id); } else if (conferenceInfo.error === 'AUTH') { // Authenentication error. Implement a function to build the correct // authenication URL for the third-party conferencing system. var authenticationUrl = getAuthenticationUrl(); var error = ConferenceDataService.newConferenceError() .setConferenceErrorType( ConferenceDataService.ConferenceErrorType.AUTHENTICATION) .setAuthenticationUrl(authenticationUrl); dataBuilder.setError(error); } else { // Other error type; var error = ConferenceDataService.newConferenceError() .setConferenceErrorType( ConferenceDataService.ConferenceErrorType.TEMPORARY); dataBuilder.setError(error); } // Don't forget to build the ConferenceData object. return dataBuilder.build(); } /** * Contact the third-party conferencing system to create a conference there, * using the provided calendar event information. Collects and retuns the * conference data returned by the third-party system in a custom JSON object * with the following fields: * * data.adminEmail - the conference administrator's email * data.conferenceLegalNotice - the conference legal notice text * data.error - Only present if there was an error during * conference creation. Equal to 'AUTH' if the add-on user needs to * authorize on the third-party system. * data.id - the conference ID * data.phoneNumber - the conference phone entry point phone number * data.phonePin - the conference phone entry point PIN * data.videoPasscode - the conference video entry point passcode * data.videoUri - the conference video entry point URI * * The above fields are specific to this example; which conference information * your add-on needs is dependent on the third-party conferencing system * requirements. * * @param {Object} calendarEvent A Calendar Event resource object returned by * the Google Calendar API. * @return {Object} */ function create3rdPartyConference(calendarEvent) { var data = {}; // Implementation details dependent on the third-party system API. // Typically one or more API calls are made to create the conference and // acquire its relevant data, which is then put in to the returned JSON // object. return data; } /** * Return the URL used to authenticate the user with the third-party * conferencing system. * * @return {String} */ function getAuthenticationUrl() { var url; // Implementation details dependent on the third-party system. return url; }
Syncing.gs
/** * Initializes syncing of conference data by creating a sync trigger and * sync token if either does not exist yet. * * @param {String} calendarId The ID of the Google Calendar. */ function initializeSyncing(calendarId) { // Create a syncing trigger if it doesn't exist yet. createSyncTrigger(calendarId); // Perform an event sync to create the initial sync token. syncEvents({'calendarId': calendarId}); } /** * Creates a sync trigger if it does not exist yet. * * @param {String} calendarId The ID of the Google Calendar. */ function createSyncTrigger(calendarId) { // Check to see if the trigger already exists; if does, return. var allTriggers = ScriptApp.getProjectTriggers(); for (var i = 0; i < allTriggers.length; i++) { var trigger = allTriggers[i]; if (trigger.getTriggerSourceId() == calendarId) { return; } } // Trigger does not exist, so create it. The trigger calls the // 'syncEvents()' trigger function when it fires. var trigger = ScriptApp.newTrigger('syncEvents') .forUserCalendar(calendarId) .onEventUpdated() .create(); } /** * Sync events for the given calendar; this is the syncing trigger * function. If a sync token already exists, this retrieves all events * that have been modified since the last sync, then checks each to see * if an associated conference needs to be updated and makes any required * changes. If the sync token does not exist or is invalid, this * retrieves future events modified in the last 24 hours instead. In * either case, a new sync token is created and stored. * * @param {Object} e If called by a event updated trigger, this object * contains the Google Calendar ID, authorization mode, and * calling trigger ID. Only the calendar ID is actually used here, * however. */ function syncEvents(e) { var calendarId = e.calendarId; var properties = PropertiesService.getUserProperties(); var syncToken = properties.getProperty('syncToken'); var options; if (syncToken) { // There's an existing sync token, so configure the following event // retrieval request to only get events that have been modified // since the last sync. options = { syncToken: syncToken }; } else { // No sync token, so configure to do a 'full' sync instead. In this // example only recently updated events are retrieved in a full sync. // A larger time window can be examined during a full sync, but this // slows down the script execution. Consider the trade-offs while // designing your add-on. var now = new Date(); var yesterday = new Date(); yesterday.setDate(now.getDate() - 1); options = { timeMin: now.toISOString(), // Events that start after now... updatedMin: yesterday.toISOString(), // ...and were modified recently maxResults: 50, // Max. number of results per page of responses orderBy: 'updated' } } // Examine the list of updated events since last sync (or all events // modified after yesterday if the sync token is missing or invalid), and // update any associated conferences as required. var events; var pageToken; do { try { options.pageToken = pageToken; events = Calendar.Events.list(calendarId, options); } catch (err) { // Check to see if the sync token was invalidated by the server; // if so, perform a full sync instead. if (err.message === "Sync token is no longer valid, a full sync is required.") { properties.deleteProperty('syncToken'); syncEvents(e); return; } else { throw new Error(err.message); } } // Read through the list of returned events looking for conferences // to update. if (events.items && events.items.length > 0) { for (var i = 0; i < events.items.length; i++) { var calEvent = events.items[i]; // Check to see if there is a record of this event has a // conference that needs updating. if (eventHasConference(calEvent)) { updateConference(calEvent, calEvent.conferenceData.conferenceId); } } } pageToken = events.nextPageToken; } while (pageToken); // Record the new sync token. if (events.nextSyncToken) { properties.setProperty('syncToken', events.nextSyncToken); } } /** * Returns true if the specified event has an associated conference * of the type managed by this add-on; retuns false otherwise. * * @param {Object} calEvent The Google Calendar event object, as defined by * the Calendar API. * @return {boolean} */ function eventHasConference(calEvent) { var name = calEvent.conferenceData.conferenceSolution.name || null; // This version checks if the conference data solution name matches the // one of the solution names used by the add-on. Alternatively you could // check the solution's entry point URIs or other solution-specific // information. if (name) { if (name === "My Web Conference" || name === "My Recorded Web Conference") { return true; } } return false; } /** * Update a conference based on new Google Calendar event information. * The exact implementation of this function is highly dependant on the * details of the third-party conferencing system, so only a rough outline * is shown here. * * @param {Object} calEvent The Google Calendar event object, as defined by * the Calendar API. * @param {String} conferenceId The ID used to identify the conference on * the third-party conferencing system. */ function updateConference(calEvent, conferenceId) { // Check edge case: the event was cancelled if (calEvent.status === 'cancelled' || eventHasConference(calEvent)) { // Use the third-party API to delete the conference too. } else { // Extract any necessary information from the event object, then // make the appropriate third-party API requests to update the // conference with that information. } }
Kliknij Ustawienia projektu .
Zaznacz pole Wyświetlaj plik manifestu „appsscript.json” w edytorze.
Kliknij Edytor
.Otwórz plik
appsscript.json
i zastąp jego zawartość tym kodem, a potem kliknij Zapisz .appsscript.json
{ "addOns": { "calendar": { "conferenceSolution": [{ "id": 1, "name": "My Web Conference", "logoUrl": "https://lh3.googleusercontent.com/...", "onCreateFunction": "createConference" }], "currentEventAccess": "READ_WRITE" }, "common": { "homepageTrigger": { "enabled": false }, "logoUrl": "https://lh3.googleusercontent.com/...", "name": "My Web Conferencing" } }, "timeZone": "America/New_York", "dependencies": { "enabledAdvancedServices": [ { "userSymbol": "Calendar", "serviceId": "calendar", "version": "v3" } ] }, "webapp": { "access": "ANYONE", "executeAs": "USER_ACCESSING" }, "exceptionLogging": "STACKDRIVER", "oauthScopes": [ "https://www.googleapis.com/auth/calendar.addons.execute", "https://www.googleapis.com/auth/calendar.events.readonly", "https://www.googleapis.com/auth/calendar.addons.current.event.read", "https://www.googleapis.com/auth/calendar.addons.current.event.write", "https://www.googleapis.com/auth/script.external_request", "https://www.googleapis.com/auth/script.scriptapp" ] }
Skopiuj numer projektu Cloud
- W konsoli Google Cloud kliknij Menu > Administracja > Ustawienia.
- W polu Numer projektu skopiuj wartość.
Ustawianie projektu Google Cloud w projekcie Apps Script
- W projekcie Apps Script kliknij Ustawienia projektu .
- W sekcji Projekt Google Cloud Platform (GCP) kliknij Zmień projekt.
- W polu Numer projektu GCP wklej numer projektu Google Cloud.
- Kliknij Ustaw projekt.
Instalowanie testowego wdrożenia
- W projekcie Apps Script kliknij Edytor.
- Otwórz plik
CreateConf.gs
i kliknij Uruchom. Gdy pojawi się odpowiedni komunikat, autoryzuj skrypt. - Kliknij Wdróż > Testuj wdrożenia.
- Kliknij Zainstaluj > Gotowe.
Uruchamianie skryptu
- Wejdź na calendar.google.com.
- Utwórz nowe wydarzenie lub otwórz istniejące.
- Obok opcji Dodaj rozmowę wideo w Google Meet kliknij strzałkę w dół > Moja konferencja internetowa. Wyświetla się błąd Nie udało się utworzyć konferencji, ponieważ dodatek nie jest połączony z prawdziwym rozwiązaniem konferencyjnym innej firmy.
Dalsze kroki
- Rozszerzanie Google Workspace za pomocą dodatków
- Tworzenie dodatków do Google Workspace
- Publikowanie aplikacji