Develop a Chat app with Apps Script

Apps Script is one of the quickest ways to create a Chat app for Google Chat.

  • You can get an app up and running in just a few minutes directly in your browser.
  • You don't need to worry about running and managing servers, ongoing maintenance or operational costs, or even downloading and setting up a development environment.
  • It's very easy to call Google APIs—especially Google Workspace APIs—because with Apps Script there's no download or setup, auth is handled automatically, and Google API calls are just like native function calls.

This guide explains how to create and register an app using Apps Script.

Getting started

This section shows you how to quickly create a Chat app using Apps Script.

Step 1: Copy the Apps Script template

The easiest way to get started creating an Apps Script app is to use the Chat template. This creates an Apps Script project with the methods that you need. After that, populate the methods as required to implement your app logic, or to integrate with an app that you've built. The following code shows an example of the template populated for a simple app.

/**
 * 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"));
}


Step 2: Edit the onMessage function

By default, the onMessage function in the template returns a Message object that contains text and a simple card. You can edit this function to return text or specific card widgets.

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

Step 3: Get deployment ID

Before you can register your app, you'll need to get the deploymentID for this specific app.

  1. Click Deploy > New deployment.
  2. Under Select type, click Add-on.
  3. Fill out the options and click Deploy.
  4. Under "Deployment ID," click Copy.

See the Release Management guide to learn about recommended practices for using deployment IDs.

Step 4: Register the app

You can register your app from the Google Cloud console. On the app registration screen, you enter the app name, avatar URL, and description. For testing, you can enable 'App can be messaged directly' and 'App works in spaces with multiple users'. Under connection settings, choose Apps Script and paste the deployment ID you copied in the previous step.

Connection settings to register your app.

Step 5: Test your app

To test your app, you can start a DM with it or @mention it into a Space. When you talk to it, it will respond to whatever the Message response is in Step 2. That's it!

Apps Script app concepts

Events

Apps Script supports several event handler functions that your app can implement. Each function handles a different event type and each function receives a single argument e, which is an Event object.

onAddToSpace(e)
This function is executed when your app is added to a space. Your app can either be directly added to the space or added through an @mention. In the second case, the event e will also have a message property. This function should return a Message object, which is usually a welcome message to tell end users about your app or a response to the @mention.
onMessage(e)
This function is called when your app is already in the space and the user @mentions your app. It should return a Message object containing your app's response.
onRemoveFromSpace(e)
This function is called when the user removes your app from their DM list or from a space. The return value of this function is ignored since your app has been removed and cannot post any more messages.

The following example implements onAddToSpace and onRemoveFromSpace:

// 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) {}

Note that e.space.displayName might not be present in direct messages between humans.

Interactive cards

Like other apps, Apps Script apps can display cards that are interactive. To learn about how to make cards interactive, check out that documentation on interactive cards. The main difference for Apps Script apps is that they can specify a specific method to call when the onClick event is triggered by using action.actionMethodName and action.parameters key/value pairs as method parameters.

Authorization

Apps Script apps that access protected resources need to ask users to authorize this access the first time it runs for each user. This doesn't require any work from you, but you should be aware that users may see an authorization dialog the first time they use your app.

Apps Script handles authorization at the script level. Apps that require authorization cannot perform any actions until the end user authorizes the app. If you would like your app to show a welcome message when it has not been authorized and is directly added to a space, you can specify a fallback message in the manifest. If your app requires initialization logic, you may need to duplicate this logic in the onMessage action. For example:

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.
  ...
}

Async messages

Some apps might need to send messages into Google Chat based on an external trigger, such as a Time-driven trigger in Apps Script.

We plan to natively integrate the Google Chat API into Apps Script for this use case. In the meantime, the only way to achieve this currently is via the external HTTP API (see documentation). This requires the use of a Cloud service account (see documentation) through the OAuth2 for Apps Script library.

The following full example app that posts a message every minute to every space it's in:

// 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),
  });
}

Manifest file

The following is an example of the Apps Script manifest file that must accompany your script.

If you did not start your project from the Chat template, then you need to edit the manifest file to add the "chat": {} object to it.

In the manifest file, set the runtime to Rhino: "runtimeVersion": "DEPRECATED_ES5". Chat apps don't fully support the Apps Script V8 runtime, so if you specify "runtimeVersion": "V8", your Chat app might error erratically. For example, JSON response structure can situationally change in unpredictable ways for Chat apps built with the V8 runtime.

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

It's possible for a user to add your app to a space before authorizing your app. In this case, your app is unable to respond to the add-to-space event. You can provide a welcome message to display if this occurs, using the addToSpaceFallbackMessage field.

The manifest file is named appsscript.json and is part of your Apps Script project. To view the manifest file in the Apps Script editor, select View > Show manifest file.