Apps Script를 사용하여 Chat 앱 개발

컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요.

Apps Script를 사용하면 Google Chat용 Chat 앱을 가장 빠르게 만들 수 있습니다.

  • 단 몇 분 만에 브라우저에서 바로 앱을 실행할 수 있습니다.
  • 서버 실행 및 관리, 지속적인 유지보수 또는 운영 비용, 개발 환경 다운로드 및 설정에 대해 걱정할 필요가 없습니다.
  • Google API, 특히Google Workspace API는 매우 쉽게 호출할 수 있습니다. Apps Script를 사용하면 다운로드나 설정이 필요 없고 인증이 자동으로 처리되며 Google API 호출은 네이티브 함수 호출과 유사하기 때문입니다.

이 가이드에서는 Apps Script를 사용하여 앱을 만들고 등록하는 방법을 설명합니다.

시작하기

이 섹션에서는 Apps Script를 사용하여 채팅 앱을 빠르게 만드는 방법을 설명합니다.

1단계: Apps Script 템플릿 복사

Apps Script 앱을 만드는 가장 쉬운 방법은 Google Chat 앱 템플릿을 사용하는 것입니다. 이렇게 하면 필요한 메서드가 포함된 Apps Script 프로젝트가 생성됩니다. 그런 다음 앱 로직을 구현하거나 빌드한 앱과 통합하기 위해 필요에 따라 메서드를 채웁니다. 다음 코드는 간단한 앱을 위해 작성된 템플릿의 예를 보여줍니다.

/**
 * Responds to a MESSAGE event in Google Chat.
 *
 * @param {Object} event the event object from Google Chat
 */
function onMessage(event) {
  var name = "";

  if (event.space.type == "DM") {
    name = "You";
  } else {
    name = event.user.displayName;
  }
  var message = name + " said \"" + event.message.text + "\"";

  return { "text": message };
}

/**
 * Responds to an ADDED_TO_SPACE event in Google Chat.
 *
 * @param {Object} event the event object from Google Chat
 */
function onAddToSpace(event) {
  var message = "";

  if (event.space.singleUserBotDm) {
    message = "Thank you for adding me to a DM, " + event.user.displayName + "!";
  } else {
    message = "Thank you for adding me to " +
        (event.space.displayName ? event.space.displayName : "this chat");
  }

  if (event.message) {
    // Bot added through @mention.
    message = message + " and you said: \"" + event.message.text + "\"";
  }

  return { "text": message };
}

/**
 * Responds to a REMOVED_FROM_SPACE event in Google Chat.
 *
 * @param {Object} event the event object from Google Chat
 */
function onRemoveFromSpace(event) {
  console.info("Bot removed from ",
      (event.space.name ? event.space.name : "this chat"));
}


2단계: onMessage 함수 수정

기본적으로 템플릿의 onMessage 함수는 텍스트와 간단한 카드가 포함된 Message 객체를 반환합니다. 이 함수를 수정하여 텍스트 또는 특정 카드 위젯을 반환할 수 있습니다.

function onMessage(e) {
  return { 'text': 'You said: \`' + e.message.text + '\`' };
}

3단계: 배포 ID 가져오기

앱을 등록하려면 이 앱의 배포 ID를 가져와야 합니다.

  1. 배포 > 새 배포를 클릭합니다.
  2. 유형 선택에서 부가기능을 클릭합니다.
  3. 옵션을 작성하고 배포를 클릭합니다.
  4. '배포 ID'에서 복사를 클릭합니다.

배포 ID 사용에 대한 권장사항은 출시 관리 가이드를 참조하세요.

4단계: 앱 등록

Google Cloud 개발자 콘솔에서 앱을 등록할 수 있습니다. 앱 등록 화면에 앱 이름, 아바타 URL, 설명을 입력합니다. 테스트를 위해 '앱에 직접 메시지를 보낼 수 있습니다' 및 '앱이 여러 사용자가 있는 공간에서 작동합니다'를 사용 설정할 수 있습니다. 연결 설정에서 Apps Script를 선택하고 이전 단계에서 복사한 배포 ID를 붙여넣습니다.

5단계: 앱 테스트

앱을 테스트하려면 DM을 시작하거나 스페이스에 @멘션하면 됩니다. 이 항목을 말하면 2단계의 메시지 응답이 무엇이든 응답합니다. 이제 완료됐습니다.

Apps Script 앱 개념

이벤트

Apps Script는 앱에서 구현할 수 있는 여러 이벤트 핸들러 함수를 지원합니다. 각 함수는 다양한 이벤트 유형을 처리하고 각 함수는 인수 객체인 단일 인수 e를 수신합니다.

onAddToSpace(e)
이 함수는 앱이 스페이스에 추가될 때 실행됩니다. 앱은 스페이스에 직접 추가하거나 @멘션을 통해 추가할 수 있습니다. 두 번째 경우 e 이벤트에는 message 속성도 있습니다. 이 함수는 Message 객체를 반환해야 합니다. 이 객체는 일반적으로 앱이나 @멘션에 관한 응답을 최종 사용자에게 알리는 환영 메시지입니다.
onMessage(e)
이 함수는 앱이 이미 스페이스에 있고 사용자가 앱을 @멘션할 때 호출됩니다. 앱의 응답이 포함된 Message 객체를 반환해야 합니다.
onRemoveFromSpace(e)
이 함수는 사용자가 DM 목록이나 스페이스에서 앱을 삭제할 때 호출됩니다. 앱이 삭제되었고 더 이상 메시지를 게시할 수 없으므로 이 함수의 반환 값은 무시됩니다.

다음 예에서는 onAddToSpaceonRemoveFromSpace를 구현합니다.

// onAddToSpace() is invoked when the app is added to a space or when
// a user initiates / re-initiates a direct message with the app.
function onAddToSpace(e) {
  if (!e.space.singleUserBotDm) {
    return { 'text': 'Thanks for adding me to "' +
        (e.space.displayName ? e.space.displayName : "this chat") + '"!' };
  } else {
    return { 'text': 'Thanks for adding me to a DM!' };
  }
}
// onRemoveFromSpace() is invoked when app is removed from a space
// or when a user removes a direct message with the app.
function onRemoveFromSpace(e) {}

e.space.displayName는 사람 간의 채팅 메시지에 없을 수 있습니다.

양방향 카드

다른 앱과 마찬가지로 Apps Script 앱은 대화형 카드를 표시할 수 있습니다. 카드를 양방향으로 만드는 방법에 관한 자세한 내용은 양방향 카드에 관한 문서를 참고하세요. Apps Script 앱의 주요 차이점은 onClick 이벤트가 트리거될 때 action.actionMethodName 및 action.parameters 키/값 쌍을 메서드 매개변수로 사용하여 호출할 특정 메서드를 지정할 수 있다는 것입니다.

확인할 내용

보호되는 리소스에 액세스하는 Apps Script 앱은 각 사용자에게 이 권한을 처음 실행할 때 이 액세스를 승인하도록 사용자에게 요청해야 합니다. 이 경우 개발자는 별도의 작업을 할 필요가 없지만, 사용자가 앱을 처음 사용할 때 승인 대화상자가 표시될 수 있다는 점에 유의해야 합니다.

Apps Script는 스크립트 수준에서 승인을 처리합니다. 승인이 필요한 앱은 최종 사용자가 앱을 승인할 때까지 어떠한 작업도 수행할 수 없습니다. 앱이 승인되지 않고 스페이스에 직접 추가되었을 때 환영 메시지를 표시하려면 매니페스트에서 대체 메시지를 지정하면 됩니다. 앱에 초기화 로직이 필요한 경우 onMessage 작업에서 이 로직을 복제해야 할 수 있습니다. 예를 들면 다음과 같습니다.

function onMessage(event) {
  var userProperties = PropertiesService.getUserProperties();
  if (!userProperties.getProperty('initialized')) {
    // handle the onAddToSpace initialization logic here.
    ...
    userProperties.setProperties({initialized: 'true'});
  }
  // Handle normal onMessage logic.
  ...
}

비동기 메시지

일부 앱은 Apps Script의 시간 기반 트리거와 같은 외부 트리거를 기반으로 Google Chat에 메시지를 보내야 할 수 있습니다.

이 사용 사례에서는 기본적으로 Google Chat API를 Apps Script에 통합할 계획입니다. 그때까지는 외부 HTTP API를 통해서만 이 작업을 달성할 수 있습니다 (문서 참조). 이를 위해서는 Apps Script 라이브러리용 OAuth2를 통해 Cloud 서비스 계정을 사용해야 합니다 (문서 참조).

다음과 같은 전체 예 앱은 1분마다 메시지를 게시합니다.

// Example app for Google Chat that demonstrates app-initiated messages
// by spamming the user every minute.
//
// This app makes use of the Apps Script OAuth2 library at:
//     https://github.com/googlesamples/apps-script-oauth2
//
// Follow the instructions there to add the library to your script.

// When added to a space, we store the space's ID in ScriptProperties.
function onAddToSpace(e) {
  PropertiesService.getScriptProperties()
      .setProperty(e.space.name, '');
  return {
    'text': 'Hi! I\'ll post a message here every minute. ' +
            'Please remove me after testing or I\'ll keep spamming you!'
  };
}

// When removed from a space, we remove the space's ID from ScriptProperties.
function onRemoveFromSpace(e) {
  PropertiesService.getScriptProperties()
      .deleteProperty(e.space.name);
}

// Add a trigger that invokes this function every minute via the
// "Edit > Current Project's Triggers" menu. When it runs, it will
// post in each space the app was added to.
function onTrigger() {
  var spaceIds = PropertiesService.getScriptProperties()
      .getKeys();
  var message = { 'text': 'Hi! It\'s now ' + (new Date()) };
  for (var i = 0; i < spaceIds.length; ++i) {
    postMessage(spaceIds[i], message);
  }
}
var SCOPE = 'https://www.googleapis.com/auth/chat.bot';
// The values below are copied from the JSON file downloaded upon
// service account creation.
// For SERVICE_ACCOUNT_PRIVATE_KEY, remember to include the BEGIN and END lines of the private key
var SERVICE_ACCOUNT_PRIVATE_KEY = '...';
var SERVICE_ACCOUNT_EMAIL = 'service-account@project-id.iam.gserviceaccount.com';

// Posts a message into the given space ID via the API, using
// service account authentication.
function postMessage(spaceId, message) {
  var service = OAuth2.createService('chat')
      .setTokenUrl('https://accounts.google.com/o/oauth2/token')
      .setPrivateKey(SERVICE_ACCOUNT_PRIVATE_KEY)
      .setClientId(SERVICE_ACCOUNT_EMAIL)
      .setPropertyStore(PropertiesService.getUserProperties())
      .setScope(SCOPE);
  if (!service.hasAccess()) {
    Logger.log('Authentication error: %s', service.getLastError());
    return;
  }
  var url = 'https://chat.googleapis.com/v1/' + spaceId + '/messages';
  UrlFetchApp.fetch(url, {
    method: 'post',
    headers: { 'Authorization': 'Bearer ' + service.getAccessToken() },
    contentType: 'application/json',
    payload: JSON.stringify(message),
  });
}

매니페스트 파일

다음은 스크립트와 함께 제공되어야 하는 Apps Script 매니페스트 파일의 예입니다. Google Chat 앱 템플릿에서 프로젝트를 시작하지 않은 경우 매니페스트 파일을 수정하여 "chat": {} 객체를 추가해야 합니다.

{
  "timeZone": "America/Los_Angeles",
  "dependencies": {},
  "chat": {
    "addToSpaceFallbackMessage": "Thank you for adding me!"
  },
  "exceptionLogging": "STACKDRIVER"
}

사용자가 앱을 승인하기 전에 스페이스에 앱을 추가할 수 있습니다. 이 경우 앱이 스페이스에 추가 이벤트에 응답할 수 없습니다. 이 경우 addToSpaceFallbackMessage 필드를 사용하여 표시할 환영 메시지를 제공할 수 있습니다.

매니페스트 파일의 이름은 appsscript.json이며 Apps Script 프로젝트의 일부입니다. Apps Script 편집기에서 매니페스트 파일을 보려면 보기 > 매니페스트 파일 표시를 선택합니다.