Creating Webhooks for Google Chat App with Apps Script

Create Webhooks for Google Chat App In Apps Script

In this tutorial, we follow the adventures of Captain Webhook and his crew in their insatiable desire to report their latest booty conquest to me via Google Chat webhooks…

That, dear readers, did not come out right.

Webhooks are HTTP POST requests that are usually generated by a triggered event. The event could come from any third-party source within Google Workspace like:

Or it can occur with other third-party services. Imagine that you want to get an update from:

  • Your Stripe or PayPal account whenever a new payment comes in.
  • A course management service like Gumroad.
  • Patreon when another awesome supporter shows you some love.

Or when a rather rambunctious figment of my imagination insists on updating me when his latest haul of treasure has come in… live.


Captain Webhook of the Pirate Sheet HTTPS Request

Chat App webhooks will need an intermediary step for them to be compiled in a way that the Google Chat API can understand. We’ve chosen Google Apps Script here to do this, but you can choose to use any other language to convert your data into Chat API readable JSON or even build in a CLI to post your webhook request.

In this tutorial, we will cover how to:

The Starter Google Apps Script Project

Grab your copy of the starter Google Apps Script project below so that you can play along. It’s got some extra code snippets in there to save you some time during the tutorial.

Besides, you’ll miss out on the fun if you just read along.

Once open, select Project details from the sidebar and then select the copy icon.

Make a copy of Google Apps Script file

The Video Tutorial

Hire me for our next Google Workspace project.

Set up your Google Chat Space to receive a webhook.

Head over to either Gmail or Google Chat and create a new Space. Alternatively, you can add the webhook to an existing space too.

I’ll be working directly in Google Chat for this example.

Create a new Google Chat Space

In Google Chat, open:

  1. Open the sidebar.
  2. Select the plus button next to the Spaces (or even the ‘Chat’ section).
  3. Select Create space.

Create a Google Chat Space

A dialogue box with appear with options to create a new Google Chat Space.

  1. Select a memorable icon or image.
  2. Add a title.
  3. Describe the Space for the benefit of the users.
  4. Add your users to the Space.
  5. Set up who can access the Space.
  6. Select Create.

Setup a Google Chat Space v2

Create a URL to the Chat Space

You will now need to create a URL to the Space. This will contain a unique key and token that your webhook will use to access the space.

  1. The title of the Space has a dropdown icon to the right of it. Select it.
  2. Then select Apps and Integration. 

Assign a webhook to a Chat App Space

This will open the Apps and Integration page.

  1. Scroll to the bottom where it says Webhooks. 
  2. Select the Add webhooks button.
  3. Add a title for the webhook. In our example, we will use “Booty Reports”.
  4. Add an avatar to represent the incoming messages for your webhook. Add the following link for this:
  5. Select Save.

Create incoming webhooks for Google Sheect link creation screen

This will generate a custom webhook link containing a unique token and key.

To get a copy of the link:

?You can support me for free by using this Amazon affiliate link in your next tech purchase :Computers & Stuff! ?
  1. Click the 3 vertical ellipses to the right of the new webhook.
  2. Select copy.

Create incoming webhooks for Google Sheect copy the webhook link v2

Your webhook URL should look a little like this:

Make sure that you keep your key and token a secret. This can be used by anyone to submit messages to your Google Chat Space.

Create and Publish Google Workspace Add-ons with Apps Script Course 300px

Create your first Google Chat App Webhook

Now that you have your delightful little copy of your webhook URL it is time to head over to your copy of the Starter Apps Script Project.

We’re going to add the following code:

Here we are using Google Apps Script UrlFetchApp class fetch method to make a post request to our wehook URL.

As you can see on line 12 the fetch method can take two parameters:

  1. The URL to request.
  2. A list of options that include the method type, header info and possibly a payload of data to send.

Line 2: Sets the webhook URL as our URL variable.

Lines 3:  Creates the options constant variable that will be added to the second parameter of the fetch method.

Line 4: Here we must declare the URL request type as ‘POST’ to indicate that we are sending data.

Line 5 – 7: Next, for the header data we will need to set our content type to JSON. This is how the Chat API will receive the data and convert it into a message.

Lines  8 – 10: We then set the payload of data that we want to send to the Chat API.

Chat App data needs to be converted into JSON format for the Chat API parse. This payload data has a limited set of commands that you can use to send text or even a stylised card to the Google Chat Space.

In the example above, we are sending a simple text to the Chat Space.

Line 12: As mentioned above, this is the stage in which we execute the fetch request. We will store the results in the response constant variable.

Line 13: While not entirely necessary, it will be helpful for us to later see what the Google Chat API returns when the message is sent successfully.

Note! While I would normally include a way to handle a bad connection, I have omitted this from this tutorial to focus on sending messages. One simple option for handling errors is to use the muteHttpExceptions property set to true in the header. This will not throw an error but record it for you to either try again or handle in future. This is, in my opinion, a more elegant option to using a JavaScript Try…Catch Statement.

Running your Webhook

The power of incorporating webhooks into a Google Chat Space is that you can receive regular updates or updates triggered on events right in chat.

For now, lest just run our code to trigger our webhook post request. You, I and… sigh… Captian Webhook’s crew will simulate a more useful (Questionable) event in our last activity in this tutorial.

In your Google Apps Script IDE,  select the webhook_v1 you created and of course did not just copy and paste in, and run the code.

The first time through you will need to run through the authorisation process.

Running Google Apps Script for the First Time: What’s with all the Warnings!

You then may need to run the function again.

On a successful run, you should see the following JSON string returned from your Chat API:

And of course, the most important part, the result, in the Chat Space:

Google Chat App Webhook Text MessageYay! I mean Yarh!!! Success.

Sending your Webhook Response to a Google Chat Reply

In Google Chat and Spaces we can directly reply to a message and subsequently generate a thread. This is helpful so that we don’t overburden the main thread in the chat.

Replying to a message. Create a thread.

Let’s give this a crack manually so we can see what’s going on.

Head to the space where your webhook message landed and hover over the message. You will see a little dialogue appear. Click the ‘Reply in thread’ icon.

Replying to a Google Chat and creating a thread

A thread window will appear to the right of the main messages.

  1. Reply to Captain Webhook. He is thirsty for validation.
  2. Take a look at the main thread. You will see the reply count increase by one.

Replying to a Google Chat and creating a thread from the thread window and seeing the reply count

So how do we send our webhook as a reply rather than spamming the main thread?

We can do this by generating a thread key the first time that we send our message and then referencing that thread key to reply within the thread.

Creating a Webhook Message with a Thread Key

Captain Webooks wants to send us a message each time he and his crew go on a raid. When he sends his initial message, he will generate a thread key.

When each crew member comes back with some booty they will report the treasure as a reply in the thread to keep everything in one place for that particular raid.

Let’s see how we can update the script to reply to a thread only.

In this example, we have separated the URL constant into lines for ease of reading. The first line is the URL to the Google Chat  Space and then the following lines are for each query.

Line 7: Our first query sets if and how we should reply to a message with the Google Chat App API messageReplyOption property. There are three possible options here:

  1. MESSAGE_REPLY_OPTION_UNSPECIFIED: This is the default setting and if not included in the query, will be implied. It means that the webhook will create a new thread when posted.
  2. REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD: This is used to create a new thread in conjunction with either a thread ID or a thread key. If a message with a matching thread key or ID exists, then the message will be a reply to the existing thread otherwise it will generate a new thread with the set key or the automatically generated thread ID.
  3. REPLY_MESSAGE_OR_FAIL: Similar to the previous option, this option does not generate a new thread if the current one does not exist. It will fail and return an error if no matching key or ID is found.

When creating a new thread key it might be helpful for us to use option two here just in case it already exists.

Line 8: Here we set the thread key with the thread_key property. For this example, we have set the thread key to ‘booty001’ presuming that there will be other booties in the future.

Note: At the time of writing this there has been some ongoing confusion in the documentation regarding the correct wording of the thread_key property. The previous threadKey property has since been depreciated. However, the documentation still displays some mixed properties over its docs.
Do the Google Devs a solid and write some feedback for them to let them know as I have.  

Create a new thread in Google Chat – how do you send a new specified threadkey?

Using Google Chat webhooks to place a message inside a thread:

Lines 9 & 10: Here again we add our private key and token to access the Google Chat Space with our webhook.

Everything else is essentially the same as before.

Go ahead and run webhook_v2 a few times. You will see that on the first run, it will create a new message. You will also be able to see in the logs that a thread key has been added.

The thread key property returned from a Google Chat API webhook request

However, on consecutive runs, the messages will be added as responses to the original with the same thread key.

Using a thread key to reply to a Google Chat Message with a webhook

Adding the thread key in the payload instead

An interesting alternative that I found while researching for this post is that we can also add the thread_key property to the JSON payload instead with the same result.

Check it out!

Note that we still need to include the messageReplyOption in the query.

Lines 17-19: Here we can see that this approach resembles the returned JSON object from the HTTP request. We must first call the ‘thread’ property before setting the ‘thread_key’ here.

Go ahead and give webhook_v3 a run with a little different text so that you can see it included in the current booty001 reply.

The results of creating a thread key in the payload for the Google Chat Webhook

Sending a Webhook as a Formatted Card

I know, based on my previous work using the Google Chat API that I can create stylised cards with images, buttons and fancy fonts.

You can learn more about this here:

Google Chat Apps for Google Apps Script Developers (updated 2023-11-04)

Seeing the layout of the HTTP response and how the payload is set up, I was curious to see if I could implement cards via webhook too.

Well, guess what? I can.

Now Captain Webhook and his crew can share booty  pic… wait … treasure pictures that they retrieve from their latest raid.

Adding the Card Property to the Payload

Let’s create another webhook function that will add our card to the main thread:

Adding some dummy pirate raid data

Lines 6 & 7: First, we will add some dummy data to display on our card.

In the starter sheet I have created two functions to do this:

  1. getBooty(): This retrieves a random booty type as an object containing the title and a URL to the image of the objects. Imagine the crew taking a photo of each haul as they retrieve it and updating the captain.
    The object looks like this: {type, url}.
  2. getPirate(): Similarly, this function retrieves a random pirate by name.

UPDATE the payload

Line 20: Here you can see that we have updated the payload with some text. You don’t need to have both text and a card together, but I have added it here as a reference point for you.

Line 21: Here we set the “cardsV2” property. This will take an object containing the layout of the card in the same format as the Chat API Cards  V2 structure.

We will create a separate function to generate our card object for ease of reading.

Create a function called createCard. This function will take our random booty and random pirate data and return the Google Chat V2 card object.

This sort of builder function is best reviewed in reverse order. Let’s start from the bottom.

The Card

Line 34: This encapsulates the main Card V2 object as an array of cards.

Line 35: Each card can have its own unique id.

Line 36 – 40: The card property contains a child object containing properties about the card. Each card contains a human-readable name for the card, a header object for the card and an array of sections found within the card.

The Header

Lines 9 – 11: The header object can contain a number of styling properties like title, subtitle and an icon image. For us, we are just adding a title.

The Section

Lines 27 – 32: While you can have multiple sections in a card, we have chosen just one in our example.

Each section contains an array of widgets.

For us, the bootySection object contains two widgets: one to handle some decorated text and one to display an image of the treasure retrieved.

The Widgets

Lines 13 – 21: Here we have used the decorated text widget to create a label describing the purpose of the widget (who pirated the object) and then the name of the pirate and a helpful icon of a person.

Sadly, Google Chat cards do not have a standard known icon for ‘PIRATE’. This should really be addressed!

As you can see decorated text widgets allow us to add extra information, buttons and images into the card. We can even do some minor styling of the text to colour it or add a font style.

Lines 23 – 25: Finally, we add an image of the treasure to the card via an image widget.


You can learn more about creating Chat App Cards here:

Running the Chat App Card Webhook

With both functions created, go ahead and run the webhook_v4 function.

You should get something like this:

Adding a card via a webhook in Google Chat with Apps Script

Give it a few runs to see what booty turns up.

Also, note in your logs that the card object is returned to you too.

Time for a fun demo.

Running Captain Webhooks Booty Haul – A Demo

Okay. Let’s see this in action. Here’s the setup.

  • Each time Captain Webhook conducts a raid with his crew a new unique thread key is generated.
  • First, a post on the original thread is generated to indicate a raid.
  • Then as the crew find treasure, they report the treasure along with a pic of the booty until there is no more to be pillaged.

Add the following code to your project and update the URL, key and token in the secret variable:

Then run startRaid() to begin the raid and quickly flip over to your Chat App console and see the raid in progress.

A Pirate raid in Google Chat Spaces with Webhooks in Google Apps Script

Go ahead and run another raid and see what happens.

Behind the scenes, I have created a call to create the initial raid with a unique thread key each time a raid occurs.

After that randomly scheduled events will trigger the retrieval of a random booty item by a random crew member. This will, in turn, update the Chat ten times.

Pretty fun, hey?


Hopefully, from the final example, you can see the potential for what webhooks can achieve in Google Chat.

Personally, I have set up a monitoring service for error logging for apps that I am responsible for. This way I can see what is happening live and address it quickly.

Create and Publish Google Workspace Add-ons with Apps Script Course 300px

I also get updates from my “Hire Me” pages for new potential clients and live updates from “Stripe” when a sale comes through for one of my courses or products right in my Google Chat. You know, do the Scrooge McDuck dive into the money vault thing.

I would love to hear how you would implement webhook for Google Chat in the comments. It is always amazing to see where people go with these tutorials.

And, if you want to learn more about creating Google Chat Apps in Google Apps Script, check out my free course below on creating a Currency Converter App:

Develop a Google Chat App Currency Converter with Google Apps Script

Create and Publish a Google Workspace Add-on with Apps Script Course

Need help with Google Workspace development?

My team of experts can help you with all of your needs, from custom app development to integrations and security. We have a proven track record of success in helping businesses of all sizes get the most out of Google Workspace.

Schedule a free consultation today to discuss your needs and get started or learn more about our services here.

~ Yagi



Captain Webhooks Pirate Booty
Captain Webhook wanted to express his gratitude for you making it all the way to the end of this tutorial by sharing the latest pick of his pirate booty for you.


5 thoughts on “Creating Webhooks for Google Chat App with Apps Script”

  1. great job Yagi, thank you as usual. a little question: if I try to uso the ‘Message with a Thread Key’ way (i.e. reply to an existing thread instead of spamming the main one) I don’t get toast notification on Android devices. I had a look to all settings about notifications (Google Chat settings as well as Android system and app related settings), it all seems ok. Descriptions on Google Chat settings suggest that both new threads and replies should generate notifications… do you know anything about a secret setting I’d look for? or maybe a bug? thank you

    1. Ye

      Good find. After some testing I had no luck either. Notification setting were supposed to include threads for the top option. I’ve sent a bug report in the feedback. The more of us who do the same the more likely they will address the issue.

      1. thank you again. I’ll do it. If you opened a bug report on issuetracker maybe if you share the issue id/link we can star it instead of creating new ones. otherwise I’ll do it on my own.

        1. I created an in-app bug report this time. I’m on my phone today.

Leave a Reply