หน้านี้อธิบายวิธีสร้างแอป Chat โดยใช้ Pub/Sub สถาปัตยกรรมประเภทนี้สำหรับแอป Chat จะมีประโยชน์หากองค์กรมีไฟร์วอลล์ซึ่งอาจป้องกันไม่ให้ Chat ส่งข้อความไปยังแอป Chat ของคุณได้ หรือหากแอป Chat ใช้ Google Workspace Events API อย่างไรก็ตาม สถาปัตยกรรมนี้มีข้อจำกัดดังต่อไปนี้เนื่องจากแอป Chat เหล่านี้จะส่งและรับได้เฉพาะข้อความแบบไม่พร้อมกันเท่านั้น
- ใช้กล่องโต้ตอบ ในข้อความไม่ได้ โปรดใช้ข้อความในการ์ดแทน
- อัปเดตการ์ดแต่ละใบด้วยการตอบกลับแบบพร้อมกันไม่ได้ แต่ให้อัปเดตข้อความทั้งหมดโดยการเรียกใช้เมธอด
patch
แทน
แผนภาพต่อไปนี้แสดงสถาปัตยกรรมของแอป Chat ที่สร้างด้วย Pub/Sub
ในแผนภาพก่อนหน้านี้ ผู้ใช้ที่โต้ตอบกับแอป Chat Pub/Sub จะมีโฟลว์ข้อมูลต่อไปนี้
ผู้ใช้ส่งข้อความใน Chat ไปยังแอปใน Chat ทั้งในข้อความส่วนตัวหรือในพื้นที่ใน Chat หรือเมื่อมีเหตุการณ์เกิดขึ้นในพื้นที่ใน Chat ที่แอป Chat มีการสมัครใช้บริการที่ใช้งานอยู่
Chat จะส่งข้อความไปยังหัวข้อ Pub/Sub
แอปพลิเคชันเซิร์ฟเวอร์ที่เป็นระบบคลาวด์หรือระบบภายในองค์กรที่มีตรรกะของแอป Chat จะสมัครใช้บริการหัวข้อ Pub/Sub เพื่อรับข้อความผ่านไฟร์วอลล์
(ไม่บังคับ) แอป Chat สามารถเรียกใช้ Chat API เพื่อโพสต์ข้อความแบบไม่พร้อมกันหรือดำเนินการอื่นๆ
ข้อกำหนดเบื้องต้น
Java
- บัญชี Google Workspace ที่มีสิทธิ์เข้าถึง Google Chat
- โปรเจ็กต์ Google Cloud
- โปรดตรวจสอบว่าได้เปิดการเรียกเก็บเงินสําหรับโปรเจ็กต์ที่อยู่ในระบบคลาวด์แล้ว ดูวิธีตรวจสอบสถานะการเรียกเก็บเงินของโปรเจ็กต์
- Java 11 ขึ้นไป
- Apache Maven
ตั้งค่าสภาพแวดล้อม
ก่อนใช้ Google APIs คุณต้องเปิดใช้ API ในโปรเจ็กต์ Google Cloud คุณเปิด API ได้มากกว่า 1 รายการในโปรเจ็กต์ Google Cloud เดียวเปิดใช้ Google Chat API และ Pub/Sub API ในคอนโซล Google Cloud
ตั้งค่า Pub/Sub
สร้างหัวข้อ Pub/Sub ที่ Chat API จะส่งข้อความได้ เราขอแนะนำให้ใช้หัวข้อเดียวต่อแอป Chat 1 แอป
ให้สิทธิ์ใน Chat ในการเผยแพร่หัวข้อด้วยการมอบหมายบทบาทผู้เผยแพร่ Pub/Sub ให้บัญชีบริการต่อไปนี้
chat-api-push@system.gserviceaccount.com
สร้างบัญชีบริการสำหรับแอป Chat เพื่อให้สิทธิ์กับ Pub/Sub และ Chat และบันทึกไฟล์คีย์ส่วนตัวไปยังไดเรกทอรีการทำงาน
สร้างการสมัครใช้บริการพุล สำหรับหัวข้อดังกล่าว
มอบหมายบทบาทผู้สมัครใช้บริการ Pub/Sub ในการสมัครใช้บริการ สำหรับบัญชีบริการที่คุณสร้างไว้ก่อนหน้านี้
เขียนสคริปต์
Java
ใน CLI ให้ระบุข้อมูลเข้าสู่ระบบบัญชีบริการดังนี้
export GOOGLE_APPLICATION_CREDENTIALS=SERVICE_ACCOUNT_FILE_PATH
สร้างไฟล์ชื่อ
pom.xml
ในไดเรกทอรีการทำงานในไฟล์
pom.xml
ให้วางโค้ดต่อไปนี้<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.pubsub</groupId> <artifactId>java-pubsub-app</artifactId> <version>0.1.0</version> <name>java-pubsub-app</name> <properties> <maven.compiler.target>11</maven.compiler.target> <maven.compiler.source>11</maven.compiler.source> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>com.google.cloud</groupId> <artifactId>libraries-bom</artifactId> <version>26.26.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>com.google.api-client</groupId> <artifactId>google-api-client</artifactId> <version>1.32.1</version> </dependency> <dependency> <groupId>com.google.cloud</groupId> <artifactId>google-cloud-pubsub</artifactId> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.14.2</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> </plugins> </pluginManagement> </build> </project>
สร้างโครงสร้างไดเรกทอรี
src/main/java
ในไดเรกทอรีการทำงานในไดเรกทอรี
src/main/java
ให้สร้างไฟล์ชื่อMain.java
ใน
Main.java
ให้วางรหัสต่อไปนี้import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.JsonNodeFactory; import com.fasterxml.jackson.databind.node.ObjectNode; import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.http.ByteArrayContent; import com.google.api.client.http.GenericUrl; import com.google.api.client.http.HttpContent; import com.google.api.client.http.HttpRequest; import com.google.api.client.http.HttpRequestFactory; import com.google.api.client.http.HttpTransport; import com.google.cloud.pubsub.v1.AckReplyConsumer; import com.google.cloud.pubsub.v1.MessageReceiver; import com.google.cloud.pubsub.v1.Subscriber; import com.google.pubsub.v1.PubsubMessage; import com.google.pubsub.v1.ProjectSubscriptionName; import java.io.FileInputStream; import java.util.Collections; public class Main { public static final String CREDENTIALS_PATH_ENV_PROPERTY = "GOOGLE_APPLICATION_CREDENTIALS"; // Google Cloud Project ID public static final String PROJECT_ID = PROJECT_ID; // Cloud Pub/Sub Subscription ID public static final String SUBSCRIPTION_ID = SUBSCRIPTION_ID public static void main(String[] args) throws Exception { ProjectSubscriptionName subscriptionName = ProjectSubscriptionName.of(PROJECT_ID, SUBSCRIPTION_ID); // Instantiate app, which implements an asynchronous message receiver. EchoApp echoApp = new EchoApp(); // Create a subscriber for <var>SUBSCRIPTION_ID</var> bound to the message receiver final Subscriber subscriber = Subscriber.newBuilder(subscriptionName, echoApp).build(); System.out.println("Starting subscriber..."); subscriber.startAsync(); // Wait for termination subscriber.awaitTerminated(); } } / ** * A demo app which implements {@link MessageReceiver} to receive messages. It simply echoes the * incoming messages. */ class EchoApp implements MessageReceiver { // Path to the private key JSON file of the service account to be used for posting response // messages to Google Chat. // In this demo, we are using the same service account for authorizing with Cloud Pub/Sub to // receive messages and authorizing with Google Chat to post messages. If you are using // different service accounts, please set the path to the private key JSON file of the service // account used to post messages to Google Chat here. private static final String SERVICE_ACCOUNT_KEY_PATH = System.getenv(Main.CREDENTIALS_PATH_ENV_PROPERTY); // Developer code for Google Chat API scope. private static final String GOOGLE_CHAT_API_SCOPE = "https://www.googleapis.com/auth/chat.bot"; // Response URL Template with placeholders for space id. private static final String RESPONSE_URL_TEMPLATE = "https://chat.googleapis.com/v1/__SPACE_ID__/messages"; // Response echo message template. private static final String RESPONSE_TEMPLATE = "You said: `__MESSAGE__`"; private static final String ADDED_RESPONSE = "Thank you for adding me!"; GoogleCredential credential; HttpTransport httpTransport; HttpRequestFactory requestFactory; EchoApp() throws Exception { credential = GoogleCredential.fromStream(new FileInputStream(SERVICE_ACCOUNT_KEY_PATH)) .createScoped(Collections.singleton(GOOGLE_CHAT_API_SCOPE)); httpTransport = GoogleNetHttpTransport.newTrustedTransport(); requestFactory = httpTransport.createRequestFactory(credential); } // Called when a message is received by the subscriber. @Override public void receiveMessage(PubsubMessage pubsubMessage, AckReplyConsumer consumer) { System.out.println("Id : " + pubsubMessage.getMessageId()); // handle incoming message, then ack/nack the received message try { ObjectMapper mapper = new ObjectMapper(); JsonNode dataJson = mapper.readTree(pubsubMessage.getData().toStringUtf8()); System.out.println("Data : " + dataJson.toString()); handle(dataJson); consumer.ack(); } catch (Exception e) { System.out.println(e); consumer.nack(); } } public void handle(JsonNode eventJson) throws Exception { JsonNodeFactory jsonNodeFactory = new JsonNodeFactory(false); ObjectNode responseNode = jsonNodeFactory.objectNode(); // Construct the response depending on the event received. String eventType = eventJson.get("type").asText(); switch (eventType) { case "ADDED_TO_SPACE": responseNode.put("text", ADDED_RESPONSE); // An app can also be added to a space by @mentioning it in a message. In that case, we fall // through to the MESSAGE case and let the app respond. If the app was added using the // invite flow, we just post a thank you message in the space. if(!eventJson.has("message")) { break; } case "MESSAGE": responseNode.put("text", RESPONSE_TEMPLATE.replaceFirst( "__MESSAGE__", eventJson.get("message").get("text").asText())); // In case of message, post the response in the same thread. ObjectNode threadNode = jsonNodeFactory.objectNode(); threadNode.put("name", eventJson.get("message").get("thread").get("name").asText()); responseNode.put("thread", threadNode); break; case "REMOVED_FROM_SPACE": default: // Do nothing return; } // Post the response to Google Chat. String URI = RESPONSE_URL_TEMPLATE.replaceFirst( "__SPACE_ID__", eventJson.get("space").get("name").asText()); GenericUrl url = new GenericUrl(URI); HttpContent content = new ByteArrayContent("application/json", responseNode.toString().getBytes("UTF-8")); HttpRequest request = requestFactory.buildPostRequest(url, content); com.google.api.client.http.HttpResponse response = request.execute(); } }
แทนที่รายการต่อไปนี้
PROJECT_ID
: รหัสโปรเจ็กต์ Google CloudSUBSCRIPTION_ID
: รหัสการสมัครใช้บริการ สำหรับการสมัครใช้บริการ Pub/Sub ที่คุณสร้างไว้ก่อนหน้านี้
เผยแพร่แอปไปยัง Chat
ในคอนโซล Google Cloud ให้ไปที่เมนู > API และบริการ > API และบริการที่เปิดใช้ > Google Chat API > การกำหนดค่า
กำหนดค่าแอป Chat สำหรับ Pub/Sub ดังนี้
- ในชื่อแอป ให้ป้อน
Quickstart App
- ใน URL ของรูปโปรไฟล์ ให้ป้อน
https://developers.google.com/chat/images/quickstart-app-avatar.png
- ในคำอธิบาย ให้ป้อน
Quickstart app
- ในส่วนฟังก์ชันการทำงาน ให้เลือกรับข้อความแบบ 1:1 และเข้าร่วมพื้นที่ทำงานและการสนทนากลุ่ม
- ในส่วนการตั้งค่าการเชื่อมต่อ ให้เลือก Cloud Pub/Sub และวางชื่อของหัวข้อ Pub/Sub ที่สร้างไว้ก่อนหน้านี้
- ในส่วนระดับการเข้าถึง ให้เลือกทำให้แอป Google Chat นี้พร้อมใช้งานสำหรับบุคคลและกลุ่มที่ระบุในโดเมน แล้วป้อนอีเมลของคุณ
- ในส่วนบันทึก ให้เลือกบันทึกข้อผิดพลาดในการบันทึก
- ในชื่อแอป ให้ป้อน
คลิกบันทึก
แอปพร้อมรับและตอบกลับข้อความใน Chat แล้ว
เรียกใช้สคริปต์
ใน CLI ให้เปลี่ยนเป็นไดเรกทอรีการทำงานและเรียกใช้สคริปต์:
Java
mvn compile exec:java -Dexec.mainClass=Main
เมื่อคุณเรียกใช้โค้ด แอปพลิเคชันจะเริ่มฟังข้อความที่เผยแพร่ไปยังหัวข้อ Pub/Sub
ทดสอบแอป Chat
หากต้องการทดสอบแอป Chat ให้เปิดพื้นที่ข้อความส่วนตัวด้วยแอป Chat แล้วส่งข้อความ ดังนี้
เปิด Google Chat โดยใช้บัญชี Google Workspace ที่คุณให้ไว้เมื่อเพิ่มตัวคุณเองเป็นผู้ทดสอบที่เชื่อถือได้
- คลิก แชทใหม่
- พิมพ์ชื่อแอป Chat ในช่องเพิ่มผู้คนอย่างน้อย 1 คน
เลือกแอป Chat จากผลการค้นหา ข้อความส่วนตัวจะเปิดขึ้น
- ในข้อความส่วนตัวใหม่ด้วยแอป ให้พิมพ์
Hello
แล้วกดenter
หากต้องการเพิ่มผู้ทดสอบที่เชื่อถือได้และดูข้อมูลเพิ่มเติมเกี่ยวกับการทดสอบฟีเจอร์แบบอินเทอร์แอกทีฟ โปรดดูทดสอบฟีเจอร์แบบอินเทอร์แอกทีฟสำหรับแอป Google Chat
แก้ปัญหา
เมื่อแอปหรือการ์ด Google Chat แสดงผลข้อผิดพลาด อินเทอร์เฟซ Chat จะแสดงข้อความว่า "เกิดข้อผิดพลาด" หรือ "ไม่สามารถดำเนินการตามคำขอของคุณ" บางครั้ง UI ของ Chat ไม่แสดงข้อความแสดงข้อผิดพลาด แต่แอปหรือการ์ด Chat จะให้ผลลัพธ์ที่ไม่คาดคิด เช่น ข้อความการ์ดอาจไม่ปรากฏ
แม้ว่าข้อความแสดงข้อผิดพลาดอาจไม่แสดงใน UI ของ Chat แต่ก็จะมีข้อความแสดงข้อผิดพลาดที่สื่อความหมายและข้อมูลบันทึกพร้อมช่วยคุณแก้ไขข้อผิดพลาดเมื่อเปิดการบันทึกข้อผิดพลาดสำหรับแอป Chat ไว้ หากต้องการความช่วยเหลือในการดู แก้ไขข้อบกพร่อง และการแก้ไขข้อผิดพลาด โปรดดูหัวข้อแก้ปัญหาและแก้ไขข้อผิดพลาดของ Google Chat
ล้างข้อมูล
เราขอแนะนำให้คุณลบโปรเจ็กต์ Cloud เพื่อหลีกเลี่ยงการเรียกเก็บเงินในบัญชี Google Cloud สำหรับทรัพยากรที่ใช้ในบทแนะนำนี้
- ในคอนโซล Google Cloud ให้ไปที่หน้าจัดการทรัพยากร คลิก เมนู > IAM และผู้ดูแลระบบ > จัดการทรัพยากร
- ในรายการโปรเจ็กต์ ให้เลือกโปรเจ็กต์ที่ต้องการลบ แล้วคลิกลบ
- ในกล่องโต้ตอบ ให้พิมพ์รหัสโปรเจ็กต์แล้วคลิกปิดเพื่อลบโปรเจ็กต์
หัวข้อที่เกี่ยวข้อง
หากต้องการเพิ่มฟีเจอร์อื่นๆ ลงในแอป Chat โปรดดูหัวข้อต่อไปนี้