בדף הזה מוסבר איך יוצרים אפליקציה ל-Chat באמצעות Pub/Sub. הארכיטקטורה של אפליקציות ל-Chat יכולה להיות שימושית אם יש בארגון חומת אש, שמונעת מ-Chat לשלוח הודעות לאפליקציית Chat, או אם אפליקציית Chat משתמשת ב-Google Workspace Event API. עם זאת, לארכיטקטורה הזו יש את המגבלות הבאות כי אפליקציות הצ'אט האלה יכולות לשלוח ולקבל רק הודעות אסינכרוניות:
- לא ניתן להשתמש בתיבות דו-שיח בהודעות. במקום זאת, כדאי להשתמש בהודעה בכרטיס.
- לא ניתן לעדכן כרטיסים בודדים בתגובה סינכרונית. במקום זאת, צריך לעדכן את ההודעה כולה על ידי קריאה לשיטה
patch
.
בתרשים הבא מוצגת הארכיטקטורה של אפליקציית Chat המבוססת על Pub/Sub:
בתרשים הקודם, משתמש שמקיים אינטראקציה עם אפליקציית Pub/Sub Chat מקבל את המידע הבא:
משתמש שולח הודעה ב-Chat לאפליקציית Chat, בצ'אט אישי או במרחב משותף ב-Chat, או אירוע שמתרחש במרחב משותף ב-Chat שבו יש לאפליקציית Chat מינוי פעיל.
ההודעה נשלחת ל-Pub/Sub ב-Chat.
שרת אפליקציות, שהוא מערכת בענן או מערכת מקומית שכוללת את הלוגיקה של אפליקציית Chat, נרשם לנושא Pub/Sub כדי לקבל את ההודעה דרך חומת האש.
אפשר גם להפעיל את אפליקציית Chat ל-Chat API כדי לפרסם הודעות באופן אסינכרוני או לבצע פעולות אחרות.
דרישות מוקדמות
Java
- חשבון Google Workspace עם גישה ל-Google Chat.
- פרויקט ב-Google Cloud.
- חשוב לוודא שהפעלת את החיוב בפרויקט שלך ב-Cloud. איך מאמתים את סטטוס החיוב של הפרויקטים?
- Java 11 ומעלה.
- Apache Maven
הגדרת הסביבה
כדי להשתמש ב-Google APIs, צריך להפעיל אותם בפרויקט ב-Google Cloud. אפשר להפעיל ממשק API אחד או יותר בפרויקט אחד ב-Google Cloud.במסוף Google Cloud, מפעילים את Google Chat API ואת Pub/Sub API.
הגדרת Pub/Sub
יוצרים נושא Pub/Sub שאליו ה-Chat API יכול לשלוח הודעות. מומלץ להשתמש בנושא אחד לכל אפליקציית Chat.
מעניקים ל-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 Cloud.SUBSCRIPTION_ID
: מזהה המינוי למינוי Pub/Sub שיצרתם בעבר.
פרסום האפליקציה ב-Chat
במסוף Google Cloud, נכנסים לתפריט > APIs ושירותים > Enabled APIs & Services > Google Chat API > הגדרה.
מגדירים את אפליקציית Chat ל-Pub/Sub:
- בקטע שם האפליקציה, מזינים
Quickstart App
. - בקטע כתובת URL של הדמות, יש להזין
https://developers.google.com/chat/images/quickstart-app-avatar.png
. - בתיאור, מזינים
Quickstart app
. - בקטע פונקציונליות, בוחרים באפשרות לקבל הודעות אישיות ובאפשרות הצטרפות למרחבים משותפים ולשיחות קבוצתיות.
- בקטע Connection settings (הגדרות חיבור), בוחרים באפשרות Cloud Pub/Sub ומדביקים את השם של נושא Pub/Sub שיצרתם קודם לכן.
- בקטע חשיפה, בוחרים באפשרות הגדרת האפליקציה הזו של Google Chat לזמינה לקבוצות ולאנשים ספציפיים בדומיין ומזינים את כתובת האימייל שלכם.
- בקטע Logs (יומנים), בוחרים באפשרות Log errors to Logging.
- בקטע שם האפליקציה, מזינים
לוחצים על שמירה.
האפליקציה מוכנה לקבל הודעות ולהשיב להן ב-Chat.
מריצים את הסקריפט
ב-CLI, עוברים לספריית העבודה ומריצים את הסקריפט:
Java
mvn compile exec:java -Dexec.mainClass=Main
כשמריצים את הקוד, האפליקציה מתחילה להאזין להודעות שפורסמו בנושא Pub/Sub.
בדיקה של אפליקציית Chat
כדי לבדוק את אפליקציית Chat, פותחים מרחב משותף לצ'אט אישי עם אפליקציית Chat ושולחים הודעה:
פותחים את Google Chat באמצעות חשבון Google Workspace שסיפקתם כשהוספתם את עצמכם כבודקים נאמנים.
- לוחצים על צ'אט חדש.
- בשדה אפשר לצרף אנשים נוספים, כותבים את השם של אפליקציית Chat.
בוחרים את אפליקציית Chat מתוך תוצאות החיפוש. תיפתח צ'אט אישי.
- בצ'אט האישי החדש עם האפליקציה, כותבים
Hello
ולוחצים עלenter
.
כדי להוסיף בודקים נאמנים ולקבל מידע נוסף על בדיקת תכונות אינטראקטיביות, קראו את המאמר בדיקת תכונות אינטראקטיביות לאפליקציות של Google Chat.
פתרון בעיות
כשמוצגת הודעת שגיאה באפליקציה או בכרטיס של Google Chat, מוצגת בממשק של Chat ההודעה 'משהו השתבש'. או "לא ניתן לעבד את הבקשה". לפעמים לא מוצגות הודעות שגיאה בממשק המשתמש של Chat, אבל קיבלתי תוצאה לא צפויה באפליקציה או בכרטיס של Chat. למשל, יכול להיות שלא תופיע הודעה.
יכול להיות שהודעת השגיאה לא תוצג בממשק המשתמש של Chat, אבל יש הודעות שגיאה תיאוריות ונתוני יומן שיכולים לעזור לך לתקן שגיאות כשמפעילים רישום שגיאות באפליקציות של Chat. במאמר פתרון בעיות ותיקון שגיאות ב-Google Chat אפשר לקבל עזרה בהצגה, בניפוי באגים ובתיקון שגיאות.
הסרת המשאבים
על מנת לא לצבור חיובים לחשבון Google Cloud עבור המשאבים שבהם השתמשתם במדריך הזה, מומלץ למחוק את הפרויקט ב-Cloud.
- במסוף Google Cloud, עוברים לדף Manage resources. לוחצים על תפריט > IAM ואדמין > ניהול משאבים.
- ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete .
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
נושאים קשורים
תוכלו להיעזר בפתרונות הבאים כדי להוסיף עוד תכונות לאפליקציית Chat: