Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions solutions/webhook-chat-app/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Google Chat App Webhook

Please see related guide on how to
[send messages to Google Chat with incoming webhooks](https://developers.google.com/workspace/chat/quickstart/webhooks).
52 changes: 52 additions & 0 deletions solutions/webhook-chat-app/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
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.
-->

<!-- [START chat_webhook_build] -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.google.chat.webhook</groupId>
<artifactId>webhook-app</artifactId>
<version>0.1.0</version>
<name>webhook-app</name>

<properties>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
</properties>

<dependencies>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.9.1</version>

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-critical critical

The gson dependency version 2.9.1 is outdated and has a known Denial of Service (DoS) vulnerability (CVE-2022-25647). It's crucial to use updated dependencies to avoid security risks. Please update to version 2.10.1 or later, which contains the fix.

        <version>2.10.1</version>

</dependency>
</dependencies>

<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
<!-- [END chat_webhook_build] -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* 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.
*/
package com.google.chat.webhook;

// [START chat_webhook]
import com.google.gson.Gson;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;
import java.net.URI;

public class App {
private static final String URL = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-critical critical

Hardcoding URLs with sensitive information like API keys and tokens is a major security risk. These credentials can be easily exposed if the source code is compromised or made public. It's highly recommended to externalize this configuration. For this example, you could pass the full URL as a command-line argument and read it in the main method, or use environment variables.

private static final Gson gson = new Gson();
private static final HttpClient client = HttpClient.newHttpClient();

public static void main(String[] args) throws Exception {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The main method declares throws Exception, which is too generic. This practice can hide bugs and make debugging difficult. It's better to declare the specific checked exceptions that can be thrown by client.send(), which are java.io.IOException and java.lang.InterruptedException.

Suggested change
public static void main(String[] args) throws Exception {
public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {

String message = gson.toJson(Map.of(
"text", "Hello from Java!"
));

HttpRequest request = HttpRequest.newBuilder(URI.create(URL))
.header("accept", "application/json; charset=UTF-8")
.POST(HttpRequest.BodyPublishers.ofString(message)).build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());
}
}
// [END chat_webhook]
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* Copyright 2025 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.
*/
package com.google.chat.webhook;

// [START chat_webhook_thread]
import com.google.gson.Gson;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.Map;
import java.net.URI;

public class App {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The public class name App must match the filename AppThread.java. This will cause a compilation error. Please rename the class to AppThread.

Suggested change
public class App {
public class AppThread {

private static final String URL = "https://chat.googleapis.com/v1/spaces/SPACE_ID/messages?key=KEY&token=TOKEN&messageReplyOption=REPLY_MESSAGE_FALLBACK_TO_NEW_THREAD";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-critical critical

Hardcoding URLs with sensitive information like API keys and tokens is a major security risk. These credentials can be easily exposed if the source code is compromised or made public. It's highly recommended to externalize this configuration. For this example, you could pass the full URL as a command-line argument and read it in the main method, or use environment variables.

private static final Gson gson = new Gson();
private static final HttpClient client = HttpClient.newHttpClient();

public static void main(String[] args) throws Exception {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The main method declares throws Exception, which is too generic. This practice can hide bugs and make debugging difficult. It's better to declare the specific checked exceptions that can be thrown by client.send(), which are java.io.IOException and java.lang.InterruptedException.

Suggested change
public static void main(String[] args) throws Exception {
public static void main(String[] args) throws java.io.IOException, java.lang.InterruptedException {

String message = gson.toJson(Map.of(
"text", "Hello from Java!",
"thread", Map.of(
"threadKey", "THREAD_KEY_VALUE"
)
));

HttpRequest request = HttpRequest.newBuilder(URI.create(URL))
.header("accept", "application/json; charset=UTF-8")
.POST(HttpRequest.BodyPublishers.ofString(message)).build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());

System.out.println(response.body());
}
}
// [END chat_webhook_thread]
Loading