Tích hợp các khái niệm cơ bản về AI trong các ứng dụng Google Chat

1. Trước khi bắt đầu

Các ứng dụng Google Chat có AI là gì?

Các ứng dụng Google Chat có AI sẽ làm những việc sau:

  • Đưa các dịch vụ và tài nguyên của bạn vào Google Chat để người dùng có thể nhận thông tin và thực hiện hành động mà không cần rời khỏi cuộc trò chuyện.
  • Tích hợp với các mô hình AI tạo sinh để tạo, tìm kiếm và chỉnh sửa dữ liệu như văn bản hoặc hình ảnh.
  • Hỗ trợ trải nghiệm dựa trên tác nhân bằng cách áp dụng các khái niệm về AI đàm thoại để có những lượt tương tác thực tế, tự nhiên, tinh vi và hữu ích hơn.

Tại sao nên tích hợp các ứng dụng Google Chat với AI?

Các trường hợp sử dụng điển hình thuộc các danh mục sau:

  • Tạo và chỉnh sửa nội dung. Tạo bản sao tiếp thị, soạn bài đăng trên mạng xã hội, tạo hình ảnh chân thực, sáng tác nhạc hoặc hỗ trợ tạo nội dung video.
  • Tìm kiếm và phân tích dữ liệu. Trích xuất thông tin chi tiết quan trọng từ cơ sở kiến thức không có cấu trúc, tóm tắt văn bản dài, phân loại nội dung hoặc dịch ngôn ngữ với độ chính xác và tốc độ cao hơn.
  • Cuộc trò chuyện. Tham gia vào các cuộc trò chuyện tự nhiên, giàu thông tin và hiệu quả như khi bạn trò chuyện với một trợ lý.
  • Tự động hoá nhiệm vụ. Thay mặt người dùng thực hiện các hành động, chẳng hạn như tạo sự kiện mới trên lịch, gửi tài liệu hoặc quản lý vé trong một hệ thống bên ngoài.

Khả năng tích hợp những tính năng này ngay trong giao diện quen thuộc của Google Chat là một cơ hội lớn cho bất kỳ ai muốn cải thiện trải nghiệm và hiệu suất của người dùng.

Điều kiện tiên quyết

Sản phẩm bạn sẽ tạo ra

Trong lớp học lập trình này, bạn sẽ tạo 8 ứng dụng Google Chat tối giản, tích hợp các khái niệm cơ bản về AI để cho thấy cách các khái niệm này có thể được áp dụng trong các ứng dụng thực tế. Tất cả đều được xây dựng dưới dạng tiện ích bổ sung của Google Workspace và dựa vào cấu trúc HTTP:

2f1e2c66f6e2e2f0.png

Cách thức hoạt động như sau:

  1. Người dùng gửi tin nhắn trong Google Chat cho một ứng dụng Chat, dưới dạng tin nhắn trực tiếp hoặc trong một không gian trên Chat.
  2. Một yêu cầu HTTP được gửi đến máy chủ web đang chạy dưới dạng hàm Node.js Google Cloud Run có chứa logic của ứng dụng Chat.
  3. Ngoài ra, logic của ứng dụng Chat có thể tích hợp với các dịch vụ của Google Workspace (như Lịch và Trang tính), các dịch vụ khác của Google (như Maps, YouTube và Vertex AI) hoặc các dịch vụ web khác (như hệ thống quản lý dự án hoặc công cụ phát hành vé).
  4. Máy chủ web gửi một phản hồi HTTP trở lại dịch vụ ứng dụng Chat trong Chat.
  5. Câu trả lời được gửi đến người dùng.
  6. Ngoài ra, ứng dụng Chat có thể gọi Chat API để đăng tin nhắn không đồng bộ hoặc thực hiện các thao tác khác.

Hàm Node.js Google Cloud Run của mỗi ứng dụng Google Chat đều chứa phiên bản riêng của các tệp nguồn sau đây để thực hiện các hành động cần thiết trong các bước 3 và 6 ở trên:

  • package.json: Một tệp kê khai trung tâm đóng vai trò là bản thiết kế cho dự án Node.js. Nó được dùng để xác định siêu dữ liệu, các phần phụ thuộc và tập lệnh.
  • env.js: Một tập lệnh thiết lập các hằng số cần thiết để thực thi. Bạn nên chỉnh sửa tệp này dựa trên môi trường và cấu hình.
  • index.js: Tập lệnh chính xử lý logic cho các sự kiện tương tác trên Google Chat. Chỉ loại sự kiện tin nhắn được triển khai trong lớp học lập trình này, nhưng thông thường, loại sự kiện này sẽ bao gồm các loại khác như lượt nhấp vào thẻ, lệnh gạch chéo và hộp thoại trong các ứng dụng thực tế.

Ứng dụng Prompt

Ứng dụng này dựa vào một mô hình Gemini để trò chuyện với người dùng bằng ngôn ngữ tự nhiên của họ thông qua các câu trả lời ngắn gọn và rõ ràng.

5975b36968ab597a.gif

Định dạng ứng dụng

Ứng dụng này được xây dựng dựa trên Prompt app bằng cách thêm tính năng hỗ trợ câu trả lời có định dạng văn bản đa dạng tuân thủ định dạng văn bản cụ thể của tin nhắn trong Google Chat.

bc49e0acf0838f28.gif

Ứng dụng Ground

Ứng dụng này được xây dựng dựa trên Format app bằng cách thêm tính năng hỗ trợ cho công cụ Google Tìm kiếm và trả về các nguồn trong tin nhắn trả lời bằng thẻ.

3cf232bf153f6abc.gif

Ứng dụng MCP

Ứng dụng này được xây dựng dựa trên Format app bằng cách thêm tính năng hỗ trợ cho Giao thức ngữ cảnh mô hình (MCP) của Trợ lý nhà phát triển Google Workspace.

8219c29366e9120e.gif

Ứng dụng nhiều lượt

Ứng dụng này được xây dựng trên Format app bằng cách thêm tính năng hỗ trợ bộ nhớ đàm thoại bằng cơ sở dữ liệu Google Cloud Firestore.

a819c274ce586451.gif

Ứng dụng công cụ tuỳ chỉnh

Ứng dụng này được xây dựng dựa trên Multi-turn app bằng cách thêm hỗ trợ cho công cụ tuỳ chỉnh gọi hàm gọi Google Workspace Calendar API dựa trên thông tin do người dùng cung cấp.

a1c4f586b7ab2e24.gif

Ứng dụng Stream

Ứng dụng này dựa vào một mô hình Gemini để tạo truyện ngắn dựa trên các chủ đề do người dùng cung cấp. Google Chat API được dùng để gửi kết quả và trạng thái trong tin nhắn khi có tiến triển.

fd347ba03fe86e22.gif

Ứng dụng đa phương thức

Ứng dụng này dựa vào một mô hình Gemini để chỉnh sửa hình ảnh dựa trên hướng dẫn bằng văn bản của người dùng. Các API Google Chat được dùng để tải xuống và tải lên hình ảnh dưới dạng tệp đính kèm của tin nhắn.

57574be33474bbc.gif

Kiến thức bạn sẽ học được

  • Các khái niệm cơ bản về AI có liên quan đến ứng dụng Google Chat và cách áp dụng các khái niệm đó.
  • Để truy cập vào Vertex AI bằng Google Gen AI SDK.
  • Sử dụng Google Workspace API để phát triển các tính năng mạnh mẽ và thú vị.
  • Tận dụng Cloud Run để tạo các ứng dụng Google Chat có khả năng mở rộng.

Những thứ bạn cần

  • Hoàn thành hướng dẫn nhanh Tạo ứng dụng Google Chat HTTP bằng Node.js. Lớp học lập trình này dựa trên dự án Google Cloud, ứng dụng Google Chat và hàm Google Cloud Run đã tạo.

2. Bắt đầu thiết lập

Khởi động và truy cập vào các tài nguyên

Trong phần này, bạn sẽ truy cập và định cấu hình các tài nguyên sau đây bằng trình duyệt web mà bạn muốn dùng.

Cấu hình API Google Chat

Mở Google Cloud Console trong một thẻ mới, sau đó làm theo các bước sau:

  1. Chọn dự án của bạn.
  2. Trong trường tìm kiếm của Google Cloud, hãy tìm "Google Chat API", sau đó nhấp vào Google Chat API, nhấp vào Quản lý rồi nhấp vào Cấu hình.

  1. Đặt Tên ứng dụngNội dung mô tả thành Gen AI App.
  2. Nhấp vào Lưu.

9a06649cf9285b99.png

Không gian trong Google Chat

Mở Google Chat trong thẻ mới, sau đó làm theo các bước sau:

  1. Nếu chưa thực hiện, hãy mở một không gian nhắn tin trực tiếp bằng ứng dụng Chat.
  2. Nhập Hello rồi nhấn enter, ứng dụng Chat sẽ trả lời bằng tên và hình đại diện của bạn.

e3b195c7b7b8e2af.png

Dịch vụ hàm Google Cloud Run

Mở Google Cloud Console trong một thẻ mới, sau đó làm theo các bước sau:

  1. Chọn dự án của bạn.
  2. Nhấp vào Trình đơn ☰ > Cloud Run > Dịch vụ.

  1. Trong danh sách dịch vụ, hãy nhấp vào addonchatapp, sau đó mở thẻ Nguồn.

b69df34ea0dc48a5.png

Tải mã nguồn và tài nguyên xuống thiết bị

  1. Tải kho lưu trữ này trên GitHub xuống.

  1. Trong môi trường phát triển cục bộ mà bạn muốn, hãy mở thư mục node/chat/gen-ai-apps.

3c57c15db4ebfddb.png

3. Ứng dụng Prompt

Ứng dụng này nhắc Gemini trên Vertex AI trò chuyện với người dùng bằng ngôn ngữ tự nhiên của họ thông qua các câu trả lời ngắn gọn và bằng văn bản thuần tuý. Việc triển khai dựa trên Google Gen AI SDK cho Node.js.

Xem lại các khái niệm

Ngôn ngữ tự nhiên

Mọi ngôn ngữ mà con người nói hoặc viết để giao tiếp hằng ngày, trái ngược với ngôn ngữ nhân tạo hoặc ngôn ngữ dựa trên máy tính.

Hàm Cloud Run

Các hàm Cloud Run rất phù hợp để tạo các phần phụ trợ không máy chủ, xử lý dữ liệu theo thời gian thực và tạo các ứng dụng thông minh. Không có máy chủ nào để cung cấp, quản lý, vá hoặc cập nhật. Các dịch vụ này tự động mở rộng quy mô, có tính sẵn sàng cao và khả năng chịu lỗi.

Tạo câu lệnh

Đưa ra câu lệnh là kỹ thuật tạo dữ liệu đầu vào (câu lệnh) để hướng dẫn một mô hình AI tạo sinh tạo ra kết quả mong muốn. Việc này thường bao gồm việc diễn đạt câu hỏi một cách cẩn thận, cung cấp bối cảnh, đưa ra hướng dẫn hoặc đưa ra ví dụ để nhận được câu trả lời cụ thể và phù hợp từ mô hình.

Vertex AI

Vertex AI cung cấp mọi thứ bạn cần để xây dựng và sử dụng AI tạo sinh, bao gồm các giải pháp AI, tính năng tìm kiếm và trò chuyện, hơn 130 mô hình cơ sở và một nền tảng AI hợp nhất.

c9e9c7a1945b22ac.png

Gemini

Gemini là một LLM đa phương thức của Google, có thể truy cập thông qua Vertex AI. AI giúp mọi người khai phá tiềm năng của bản thân để có thể tăng cường trí tưởng tượng, mở rộng khả năng tìm tòi và nâng cao năng suất.

SDK Google Gen AI

Google Gen AI SDK được thiết kế để nhà phát triển tạo các ứng dụng dựa trên Gemini, cung cấp một giao diện hợp nhất tương thích với cả Gemini Developer APIVertex AI. Nền tảng này đi kèm với các thư viện ứng dụng bằng Python, Go, Node.jsJava.

Quy trình xem xét

c625fdcc8b4a27f4.png

Xem mã nguồn

env.js

...
// Replace with your GCP project ID.
projectID: process.env.PROJECT_ID || 'your-google-cloud-project-id',

// Replace with your GCP project location.
location: process.env.LOCATION || 'your-google-cloud-project-location',

// Replace with the Gemini model to use.
model: process.env.MODEL || 'gemini-2.5-flash-lite',
...

index.js

// Import the Google Gen AI SDK.
import { GoogleGenAI } from '@google/genai';
...
// Use Vertex AI.
const genAI = new GoogleGenAI({vertexai: true, project: env.projectID, location: env.location});

http('gen-ai-app', async (req, res) => {
 // Send a new Chat message with the generated answer
 return res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
   text: await generateAnswer(req.body.chat.messagePayload.message.text)
 }}}}});
});

async function generateAnswer(message) {
 // The prompt is made of the user's message and specific instructions for the model.
 const prompt = 'In a consice and with plain text only (no formatting), '
                 + 'answer the following message in the same language: ' + message;
 const aiResponse = await genAI.models.generateContent({model: env.model, contents: prompt});
 return aiResponse.candidates[0].content.parts[0].text;
};
...

package.json

...
"main": "index.js",
"type": "module",
"scripts": {
  "start": "node index.js"
},
"dependencies": {
  "@google-cloud/functions-framework": "^4.0.0",
  "@google/genai": "1.15.0"
},
...

Bật Vertex AI API

  1. Trong Google Cloud Console, hãy bật API Vertex AI:

  1. Nhấp vào Trình đơn ☰ > API và Dịch vụ > API và Dịch vụ đã bật rồi xác nhận rằng Vertex AI API có trong danh sách.

Cập nhật hàm Node.js của Google Cloud Run

  1. Trong môi trường phát triển cục bộ, hãy thay đổi thư mục hiện tại thành node/chat/gen-ai-apps/1-prompt. Thư mục này chứa toàn bộ mã nguồn và tài nguyên.
  2. Mở env.js trong một trình chỉnh sửa và thiết lập như sau:
  3. projectID: Mã nhận dạng dự án của bạn trên Google Cloud. Bạn có thể truy xuất khoá này từ trang chào mừng của bảng điều khiển Google Cloud.

  1. location: Khu vực của dịch vụ hàm Google Cloud Run. Bạn có thể truy xuất khoá này từ trang chi tiết dịch vụ hàm Google Cloud Run.

  1. model: Mô hình cần sử dụng. Bạn có thể tìm thấy tất cả các mô hình hiện có trong tài liệu về Vertex AI. Mô hình được đặt theo mặc định là Flash để thực thi nhanh và rẻ.

6c2fb9f554f53a4a.png

  1. Chuyển đến thẻ Nguồn trên trang thông tin chi tiết về dịch vụ hàm Google Cloud Run.

  1. Nhấp vào Chỉnh sửa nguồn.
  2. Đặt Function entry point thành gen-ai-app.
  3. Nhấp vào , nhập env.js rồi nhấp vào ✔️ để tạo tệp nguồn bị thiếu.
  4. Thay thế toàn bộ nội dung của các tệp index.js, env.jspackage.json bằng nội dung trong môi trường phát triển cục bộ.
  5. Nhấp vào Lưu và triển khai lại.
  6. Chờ quá trình triển khai bản sửa đổi hoàn tất.

487b64f2d3b1a104.png

Thử nào

  1. Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy nhập Hello, how are you? rồi nhấn enter. Ứng dụng phải trả lời ngắn gọn bằng văn bản thuần tuý theo hướng dẫn của chúng tôi trong câu lệnh.

3cc1fd1de2a9e239.png

  1. Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy nhập Bonjour comment allez-vous? rồi nhấn enter. Ứng dụng phải trả lời bằng tiếng Pháp theo hướng dẫn của chúng tôi trong câu lệnh.

77010f4ad0bde5da.png

4. Ứng dụng Format

Ứng dụng này được xây dựng dựa trên Prompt app bằng cách thêm tính năng hỗ trợ các câu trả lời có định dạng văn bản đa dạng thức tuân thủ định dạng tin nhắn văn bản của Google Chat. Hướng dẫn trong câu lệnh được cập nhật bằng nội dung mô tả đầy đủ về các lựa chọn mà mô hình có thể sử dụng.

Xem lại các khái niệm

Tin nhắn văn bản trong Google Chat

Tin nhắn văn bản trong Google Chat hỗ trợ nhiều lựa chọn định dạng để giúp tin nhắn rõ ràng và thể hiện cảm xúc hơn ngay trong giao diện Google Chat. Chúng dựa trên các quy tắc đánh dấu cụ thể để áp dụng kiểu chữ đậm, nghiêng, gạch ngang, tạo siêu liên kết, v.v.

Quy trình xem xét

c625fdcc8b4a27f4.png

Xem xét mã nguồn

index.js

...
async function generateAnswer(message) {
 // Specify formatting options that are compatible with Google Chat messages
 // https://developers.google.com/workspace/chat/format-messages#format-texts
 const prompt = `Use simple text for concise answers. The only formatting options you can use is to
(1) surround some text with a single star for bold such as *text* for strong emphasis
(2) surround some text with a single underscore for italic such as _text_ for gentle emphasis
(3) surround some text with a single tild for strikethrough such as ~text~ for removal
(4) use a less than before followed by a URL followed by a pipe followed by a link text followed
    by a more than for a hyperlink such as <https://example.com|link text> for resource referencing
(5) use a backslash followed by the letter n for a new line such as \n for readibility
(6) surround some text with a single backquote such as \`text\` for quoting code
(7) surround an entire paragraph with three backquotes in dedicated lines such as
    \`\`\`\nparagraph\n\`\`\` for quoting code
(8) prepend lines with list items with a single star or hyphen followed by a single space
    such as * list item or - list item for bulleting ;
DO NOT USE ANY OTHER FORMATTING OTHER THAN THOSE.
Answer the following message in the same language: ${message}`;
...
};
...

Cập nhật hàm Google Cloud Run Node.js

  1. Trong môi trường phát triển cục bộ, hãy thay đổi thư mục hiện tại thành node/chat/gen-ai-apps/2-format. Thư mục này chứa toàn bộ mã nguồn và tài nguyên.
  2. Chuyển đến thẻ Nguồn trên trang thông tin chi tiết về dịch vụ hàm Google Cloud Run.

  1. Nhấp vào Chỉnh sửa nguồn.
  2. Thay thế toàn bộ nội dung của tệp index.js bằng nội dung trong môi trường phát triển cục bộ.
  3. Nhấp vào Lưu và triển khai lại.
  4. Chờ quá trình triển khai bản sửa đổi hoàn tất.

487b64f2d3b1a104.png

Thử nào

  1. Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy nhập Showcase all formatting options you have with one paragraph each rồi nhấn enter. Ứng dụng phải trả lời bằng các mẫu định dạng dựa trên hướng dẫn của chúng tôi trong câu lệnh.

cc7f7101d9f7c10.png

  1. Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy nhập What are Google Chat apps? What's great about them? rồi nhấn enter. Ứng dụng nên trả lời bằng cách định dạng khi cần thiết.

83557d4c7071aac8.png

5. Ứng dụng Ground

Ứng dụng này được xây dựng dựa trên Format app bằng cách thêm tính năng hỗ trợ cho việc xác định cơ sở và trả về nguồn. Công cụ này chạy Google Tìm kiếm và đính kèm các thẻ có đường liên kết đến câu trả lời.

Xem lại các khái niệm

Tiếp đất

Căn cứ là kỹ thuật kết nối các mô hình với nguồn thông tin. Mô hình này thường được dùng trong các ứng dụng thực tế để cải thiện độ chính xác và mức độ phù hợp của nội dung được tạo bằng cách tham chiếu dữ liệu trong thế giới thực, nhờ đó ngăn mô hình tạo ra thông tin sai lệch hoặc thông tin không chính xác.

Công cụ Google Tìm kiếm

Công cụ Google Tìm kiếm giúp tăng cường khả năng tiếp cận thông tin bằng cách cho phép các mô hình tìm kiếm thông tin theo thời gian thực trên web, đảm bảo câu trả lời chính xác và mới nhất.

Khung thẻ Google Workspace

Khung thẻ trong Google Workspace cho phép nhà phát triển tạo giao diện người dùng phong phú và có tính tương tác. Thư viện này cho phép tạo các thẻ có tổ chức và bắt mắt, có thể bao gồm văn bản, hình ảnh, nút và các tiện ích khác. Những thẻ này giúp nâng cao trải nghiệm người dùng bằng cách cung cấp thông tin có cấu trúc và cho phép thực hiện nhanh các thao tác ngay trong cuộc trò chuyện.

Quy trình xem xét

b72d69a6e79858d6.png

Xem xét mã nguồn

index.js

...
const aiResponse = await genAI.models.generateContent({
 model: env.model,
 contents: prompt,
 // Google Search tool is enabled
 config: { tools: [{ googleSearch: {}}]}
});

let groundingCardsV2 = undefined;
const grounding = aiResponse.candidates[0].groundingMetadata;
// Go through the grounding metadata if any
if (grounding && grounding.groundingChunks && grounding.groundingChunks.length > 0) {
 let linkButtons = [];
 grounding.groundingChunks.forEach(groundingChunk => {
   if (groundingChunk.web) {
     // Create one link button per web URL returned
     linkButtons.push({
       text: groundingChunk.web.domain,
       onClick: { openLink: { url: groundingChunk.web.uri}}
     });
   }
 });
 // Create a card with link buttons
 groundingCardsV2 = [{
   cardId: "sourcesCard",
   card: { sections: [{
     header: "Sources",
     widgets: [{ buttonList: { buttons: linkButtons}}]
   }]}
 }];
}

// Send a Chat message with the generated answer
return res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
 text: aiResponse.candidates[0].content.parts[0].text,
 // The sources are referenced in the card
 cardsV2: groundingCardsV2
}}}}});
...

Cập nhật hàm Google Cloud Run Node.js

  1. Trong môi trường phát triển cục bộ, hãy thay đổi thư mục hiện tại thành node/chat/gen-ai-apps/3-ground. Thư mục này chứa toàn bộ mã nguồn và tài nguyên.
  2. Chuyển đến thẻ Nguồn trên trang thông tin chi tiết về dịch vụ hàm Google Cloud Run.

  1. Nhấp vào Chỉnh sửa nguồn.
  2. Thay thế toàn bộ nội dung của tệp index.js bằng nội dung trong môi trường phát triển cục bộ.
  3. Nhấp vào Lưu và triển khai lại.
  4. Chờ quá trình triển khai bản sửa đổi hoàn tất.

487b64f2d3b1a104.png

Thử nào

Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy nhập What's the world population? rồi nhấn enter. Ứng dụng sẽ trả lời bằng cách đính kèm đường liên kết đến nguồn trong thẻ.

cff461da29c05873.png

6. Ứng dụng MCP

Ứng dụng này được xây dựng trên Format app bằng cách thêm tính năng hỗ trợ cho các công cụ do một máy chủ Giao thức ngữ cảnh mô hình (MCP) được lưu trữ từ xa cung cấp. Tiện ích này kết nối với MCP Trợ lý nhà phát triển Google Workspace. MCP này cung cấp các công cụ để truy cập và tìm kiếm tài liệu dành cho nhà phát triển Google Workspace.

Xem lại các khái niệm

Giao thức bối cảnh mô hình (MCP)

Model Context Protocol là một khung nguồn mở tích hợp các mô hình với các dịch vụ bên ngoài theo cách tiêu chuẩn. Các mô hình có thể tự động khám phá, hiểu và tương tác với nhiều công cụ, mở rộng khả năng, thực hiện các hành động trong thế giới thực và truy cập vào thông tin mới nhất.

MCP TypeScript SDK

TypeScript SDK triển khai toàn bộ quy cách MCP, giúp đơn giản hoá việc tạo các ứng dụng MCP kết nối với mọi máy chủ MCP. Việc này cũng cho phép phát triển các máy chủ MCP cung cấp quyền truy cập vào tài nguyên, câu lệnh và công cụ.

Quy trình xem xét

e0b324e2cca21915.png

Xem xét mã nguồn

index.js

// Import the MCP TypeScript SDK.
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
...
// Create and connect the MCP client from the URL.
const mcpServerUrl = new URL("https://workspace-developer.goog/mcp");
const client = new Client({ name: "gen-ai-app-mcp", version: "1.0.0" });
// Try Streamable HTTP first (new) and SSE (old) as fallback for transport
try {
 await client.connect(new StreamableHTTPClientTransport(mcpServerUrl));
} catch (error) {
 await client.connect(new SSEClientTransport(mcpServerUrl));
}

http('gen-ai-app', async (req, res) => {
 ...
 const aiResponse = await genAI.models.generateContent({
   model: env.model,
   contents: prompt,
   // MCP tools are enabled
   config: { tools: [mcpToTool(client)]}
 });
 ...
}
...

package.json

...
"dependencies": {
  ...
  "@modelcontextprotocol/sdk": "^1.18.1"
},
...

Cập nhật hàm Google Cloud Run Node.js

  1. Trong môi trường phát triển cục bộ, hãy thay đổi thư mục hiện tại thành node/chat/gen-ai-apps/4-mcp. Thư mục này chứa toàn bộ mã nguồn và tài nguyên.
  2. Chuyển đến thẻ Nguồn trên trang thông tin chi tiết về dịch vụ hàm Google Cloud Run.

  1. Nhấp vào Chỉnh sửa nguồn.
  2. Thay thế toàn bộ nội dung của tệp index.jspackage.json bằng nội dung trong môi trường phát triển cục bộ.
  3. Nhấp vào Lưu và triển khai lại.
  4. Chờ quá trình triển khai bản sửa đổi hoàn tất.

487b64f2d3b1a104.png

Thử nào

  1. Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy nhập What can you do for me? rồi nhấn enter. Ứng dụng phải mô tả những việc mà ứng dụng có thể làm (công cụ MCP).

13535bfd31d85a50.png

  1. Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy nhập I would like to get the latest official documentation for the Google Sheets API append values rồi nhấn enter. Ứng dụng sẽ trả lời bằng tài liệu được yêu cầu (bằng cách sử dụng các công cụ MCP).

8a6f4ac5b7d5fa4a.png

7. Ứng dụng nhiều lượt

Ứng dụng này được xây dựng dựa trên Format app bằng cách thêm tính năng hỗ trợ bộ nhớ trò chuyện thông qua việc theo dõi nhật ký tương tác trong cuộc trò chuyện. Điều này giúp mang đến trải nghiệm tự nhiên, thông minh và phù hợp hơn với bạn. Ứng dụng này sử dụng cơ sở dữ liệu Google Cloud Firestore mặc định được liên kết với dự án của họ trên Google Cloud để lưu trữ.

Xem lại các khái niệm

Nhiều lượt

Khái niệm nhiều lượt tương tác đề cập đến khả năng duy trì ngữ cảnh và tính liên tục của mô hình trong nhiều lượt trao đổi và trò chuyện. Đây là một tính năng bắt buộc để hỗ trợ các cuộc trò chuyện phức tạp, các chức năng tinh vi dựa trên AI và trải nghiệm tự nhiên cho người dùng.

Google Cloud Firestore

Google Cloud Firestore là một cơ sở dữ liệu đám mây NoSQL linh hoạt, có khả năng mở rộng để phát triển ứng dụng di động, web và máy chủ. Realm lưu trữ dữ liệu trong các tài liệu, được sắp xếp thành các bộ sưu tập và cho phép đồng bộ hoá theo thời gian thực cũng như hỗ trợ khi không có mạng.

Quy trình xem xét

52920a2227467218.png

Xem xét mã nguồn

index.js

// Import the Google Cloud Firestore client library.
import { Firestore } from '@google-cloud/firestore';
...
// Configure DB
const USERS_PREFIX = 'users/';
const CHATS_COLLECTION = 'chats';
const db = new Firestore();
...
// Create or update data for a given user
async function createOrUpdateChatHistory(userId, data) {
 await db.collection(CHATS_COLLECTION).doc(userId.replace(USERS_PREFIX, '')).set(data);
};

// Retrieve data snapshot for a given user
async function getChatHistory(userId) {
 return await db.collection(CHATS_COLLECTION).doc(userId.replace(USERS_PREFIX, '')).get();
};
...
...
http('gen-ai-app', async (req, res) => {
 // Retrieve the chat history of the user
 const chatHistory = await getChatHistory(userId);
 const chat = genAI.chats.create({
   model: env.model,
   // Initiate the model with chat history for context
   history: chatHistory.exists ? chatHistory.data().contents : []
 });
 // If no history, send a first message to the model with instructions on how to behave
 if(!chatHistory.exists) {
   const preambule = 'The only formatting options you can use is to '
                   + ...
                   + 'DO NOT USE ANY OTHER FORMATTING OTHER THAN THOSE. '
                   + 'Answer in the same language that I use.';
   // The answer to this message is ignored
   await chat.sendMessage({message: preambule});
 }

 // Send the user's message to the model to generate the answer
 const aiResponse = await chat.sendMessage({message: userMessage});

 // Persist the updated chat history of the user
 await createOrUpdateChatHistory(userId, {contents: chat.getHistory({curated: true})});

 // Send a Chat message with the generated answer
 return res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
   text: aiResponse.candidates[0].content.parts[0].text
 }}}}});
});
...

package.json

...
"dependencies": {
  ...
  "@google-cloud/firestore": "^7.11.5"
},
...

Bật Google Cloud Firestore API

  1. Trong Bảng điều khiển Google Cloud, hãy bật Google Cloud Firestore API:

  1. Nhấp vào Trình đơn ☰ > API và dịch vụ > API và dịch vụ đã bật, sau đó xác nhận rằng Cloud Firestore API có trong danh sách.

Tạo cơ sở dữ liệu Cloud Firestore

  1. Trong Bảng điều khiển Google Cloud, hãy nhấp vào Trình đơn ☰ > Firestore

  1. Nhấp vào Tạo cơ sở dữ liệu Firestore
  2. Giữ nguyên cấu hình mặc định rồi nhấp vào Tạo cơ sở dữ liệu

Cập nhật hàm Google Cloud Run Node.js

  1. Trong môi trường phát triển cục bộ, hãy thay đổi thư mục hiện tại thành node/chat/gen-ai-apps/5-multi-turn. Thư mục này chứa toàn bộ mã nguồn và tài nguyên.
  2. Chuyển đến thẻ Nguồn trên trang thông tin chi tiết về dịch vụ hàm Google Cloud Run.

  1. Nhấp vào Chỉnh sửa nguồn.
  2. Thay thế toàn bộ nội dung của tệp index.jspackage.json bằng nội dung trong môi trường phát triển cục bộ.
  3. Nhấp vào Lưu và triển khai lại.
  4. Chờ quá trình triển khai bản sửa đổi hoàn tất.

487b64f2d3b1a104.png

Thử nào

  1. Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy nhập Can you speak with the English from the 80's for now on? rồi nhấn enter. Ứng dụng sẽ phản hồi tích cực.

b273beda7e203b23.png

  1. Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy nhập Define what Google Chat apps are in one sentence rồi nhấn enter. Ứng dụng nên tiếp tục phản hồi bằng tiếng Anh của những năm 80.

9156f563c369f186.png

8. Ứng dụng công cụ tuỳ chỉnh

Ứng dụng này được xây dựng dựa trên Multi-turn app bằng cách thêm tính năng hỗ trợ cho một công cụ tuỳ chỉnh gọi hàm dựa trên API Lịch Google Workspace để truy xuất sự kiện tiếp theo từ một lịch công khai. Mô hình này quản lý tất cả hoạt động tương tác của người dùng, bao gồm cả việc nhận dữ liệu đầu vào và phân phối dữ liệu đầu ra từ công cụ. Tuy nhiên, ứng dụng vẫn chịu trách nhiệm thực thi các lệnh gọi API cần thiết và cung cấp kết quả cho mô hình theo yêu cầu. Ứng dụng sử dụng một Khoá API Google vì không cần thông tin đăng nhập của người dùng để tìm nạp dữ liệu lịch công khai.

Xem lại các khái niệm

Gọi hàm

Gọi hàm cho phép mô hình phát hiện thời điểm yêu cầu của người dùng có thể được thực hiện bằng một công cụ hoặc API bên ngoài. Sau đó, mô hình sẽ cung cấp các tham số cần thiết để gọi công cụ đó, tích hợp các chức năng bên ngoài vào câu trả lời của mô hình.

API Google Workspace

API Google Workspace cho phép nhà phát triển tích hợp các ứng dụng của họ với nhiều dịch vụ của Google Workspace. Các API này cung cấp quyền truy cập theo chương trình vào các chức năng trên nhiều sản phẩm như Gmail, Chat, Lịch, Drive, Tài liệu, Trang tính và nhiều sản phẩm khác, cho phép tự động hoá, đồng bộ hoá dữ liệu và tạo quy trình làm việc tuỳ chỉnh.

Quy trình xem xét

ed866ca369a4512f.png

Xem xét mã nguồn

env.js

...
// Replace with your Google API key.
googleApiKey: process.env.GOOGLE_API_KEY || 'your-google-api-key',
...

index.js

// Import parameter type definitions from Google Gen AI SDK.
import { GoogleGenAI, Type } from '@google/genai';
// Import Google APIs that include the Google Calendar API.
import { google } from 'googleapis';
...
// Create a Google Calendar API client using a Google API key.
const calendar = google.calendar({version: 'v3', auth: env.googleApiKey});
...
// Define the tool used for function calling
const getNextPublicCalendarEventTitleFunctionDeclaration = {
 name: 'getNextPublicCalendarEventTitle',
 parameters: {
   type: Type.OBJECT,
   description: 'Get the title of the next event of a public calendar.',
   properties: {
     calendarId: {
       type: Type.STRING,
       description: 'ID of the public calendar to get the next event title.',
     }
   },
   required: ['calendarId']
 }
};

// The function referenced in the tool definition
async function getNextPublicCalendarEventTitle(calendarId) {
 // Use Calendar API to retrieve the next event in the given calendar
 const response = await calendar.events.list({
   calendarId: calendarId,
   timeMin: new Date().toISOString(),
   maxResults: 1,
   singleEvents: true,
   orderBy: 'startTime',
 });
 const events = response.data.items;
 if (!events || events.length === 0) {
   return null;
 }
 return `${events[0].summary}`;
};
...
...
http('gen-ai-app', async (req, res) => {
 ...
 // Send the user's message to the model to generate the answer
 let aiResponse = await chat.sendMessage({
   message: userMessage,
   // The tool used for function calling is enabled
   config: { tools: [{ functionDeclarations: [getNextPublicCalendarEventTitleFunctionDeclaration]}]}
 });

 // Handle the function calling turn with the model if any
 const functionCall = aiResponse.candidates[0].content.parts[0].functionCall;
 if (functionCall) {
   let functionResult = null;
   switch(functionCall.name) {
     case 'getNextPublicCalendarEventTitle':
       // Make the function call as per model request
       functionResult = await getNextPublicCalendarEventTitle(functionCall.args['calendarId']);
       break;
     default:
   }
   // Finish the function calling turn by sending the execution result to the model
   aiResponse = await chat.sendMessage({ message: { functionResponse: {
     name: functionCall.name,
     response: { output: functionResult }
   }}});
 }
 ...
 // Send a Chat message with the generated answer
 return res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
   text: aiResponse.candidates[0].content.parts[0].text
 }}}}});
});
...

package.json

...
"dependencies": {
  ...
   "googleapis": "^160.0.0"
},
...

Bật Calendar API

  1. Trong Bảng điều khiển Google Cloud, hãy bật Google Calendar API:

  1. Nhấp vào Trình đơn ☰ > API và Dịch vụ > API và Dịch vụ đã bật, sau đó xác nhận rằng Google Calendar API có trong danh sách.

Tạo khoá API của Google

Trong Bảng điều khiển Google Cloud, hãy làm theo các bước sau:

  1. Nhấp vào Trình đơn ☰ > API và Dịch vụ > Thông tin xác thực.

  1. Nhấp vào + Tạo thông tin xác thực rồi chọn Khoá API.
  2. Chờ quá trình này hoàn tất.
  3. Trong hộp thoại xác nhận, hãy tìm trường văn bản Khoá API của bạn rồi nhấp vào Sao chép vào khay nhớ tạm.

Cập nhật hàm Node.js trên Google Cloud Run

  1. Trong môi trường phát triển cục bộ, hãy thay đổi thư mục hiện tại thành node/chat/gen-ai-apps/6-custom-tool. Thư mục này chứa toàn bộ mã nguồn và tài nguyên.
  2. Chuyển đến thẻ Nguồn trên trang thông tin chi tiết về dịch vụ hàm Google Cloud Run.

  1. Nhấp vào Chỉnh sửa nguồn.
  2. Thay thế toàn bộ nội dung của tệp index.jspackage.json bằng nội dung trong môi trường phát triển cục bộ.
  3. Mở tệp env.js và làm như sau
  4. Thêm googleApiKey vào các trường được xuất
export const env = {
 ...
 googleApiKey: 'your-google-api-key',
};
  1. Thay thế your-google-api-key bằng Khoá API Google mà bạn đã sao chép ở bước trước. Bạn có thể truy xuất khoá này từ trang thông tin đăng nhập của Google Cloud bằng cách nhấp vào Hiện khoá.

  1. Nhấp vào Lưu và triển khai lại.
  2. Chờ quá trình triển khai bản sửa đổi hoàn tất.

487b64f2d3b1a104.png

Thử nào

  1. Trong Lịch Google, hãy làm theo các bước sau:
  2. Trong mục Lịch khác, hãy nhấp vào biểu tượng +, rồi nhấp vào Tạo lịch mới.
  3. Đặt Name thành My Public Calendar
  4. Nhấp vào Tạo lịch
  5. Chờ quá trình này hoàn tất.
  6. Trong phần Cài đặt dành cho các lịch của tôi, hãy chọn lịch mới tạo Lịch công khai của tôi
  7. Trong phần Quyền truy cập vào sự kiện, hãy chọn Chia sẻ với mọi người, rồi nhấp vào OK trong hộp thoại Cảnh báo.
  8. Trong phần Quyền truy cập vào sự kiện, hãy chọn Xem tất cả thông tin chi tiết của sự kiện trong trình đơn thả xuống bên cạnh lựa chọn Chia sẻ với mọi người
  9. Trong mục Tích hợp lịch, hãy sao chép giá trị của trường Mã lịch vào bảng nhớ tạm
  10. Nhấp vào mũi tên bên trái ở góc trên cùng bên trái để thoát khỏi phần Cài đặt.
  11. Nhấp vào lịch để tạo một sự kiện mới cho ngày mai, nhập Important meeting, chọn Lịch công khai của tôi trong trình đơn thả xuống, sau đó nhấp vào Lưu
  12. Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy nhập When is the next meeting? rồi nhấn enter. Ứng dụng nên yêu cầu độ chính xác vì không rõ lịch nào đang được đề cập.

40383099311b0813.png

  1. Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy dán mã lịch bạn đã sao chép vào bảng nhớ tạm trước đó rồi nhấn enter. Ứng dụng sẽ trả lời bằng thông tin chi tiết về sự kiện đã tạo trước đó.

4c614c7e444e3b45.png

9. Ứng dụng phát trực tuyến

Ứng dụng này dựa vào một mô hình Gemini để tạo các câu chuyện dài 2 phút dựa trên những chủ đề do người dùng cung cấp. Vì cần có thời gian để tạo câu trả lời đầy đủ, nên ứng dụng sẽ gọi đến mô hình ở chế độ truyền trực tuyến và dựa vào Google Chat API để gửi nội dung và trạng thái trong tin nhắn khi có tiến triển.

Xem lại các khái niệm

Google Chat API

API Google Chat cho phép nhà phát triển tương tác theo phương thức lập trình với Google Chat, giúp họ gửi tin nhắn, tạo không gian, quản lý thành viên và làm nhiều việc khác để tạo các tiện ích tích hợp và bot tuỳ chỉnh.

Phát trực tuyến

Truyền trực tuyến là quá trình nhận dữ liệu liên tục thay vì chờ toàn bộ phản hồi được tạo. Đối với các lệnh gọi mô hình AI, tính năng truyền phát trực tiếp cho phép các ứng dụng hiển thị kết quả một phần cho người dùng ngay khi có kết quả, giúp cải thiện hiệu suất cảm nhận và trải nghiệm người dùng, đặc biệt là đối với các tác vụ tạo nội dung dài hơn. Điều này đặc biệt phù hợp với các mô hình AI tạo sinh vì chúng có thể mất một khoảng thời gian đáng kể để tạo ra một kết quả hoàn chỉnh.

Quy trình xem xét

25f9036eecd9a48b.png

Xem mã nguồn

index.js

// Import Google Auth library used to create Google Chat API client
import { GoogleAuth } from 'google-auth-library';
...
http('gen-ai-app', async (req, res) => {
 // Use app authentication.
 // Application Default Credentials (ADC) will use the Cloud Run function's
 // default service account, we just need to specify the Chat API app auth scopes.
 const auth = new GoogleAuth({
   // Chat API app authentication scopes
   scopes: ['https://www.googleapis.com/auth/chat.bot']
 });

 // Create Chat service client with application credentials
 const chatClient = google.chat({
   version: 'v1',
   auth: await auth.getClient()
 });

 // Send a server streaming request to generate the answer
 const aiResponse = await genAI.models.generateContentStream({
   model: env.model,
   contents: `Generate a story about a ${userMessage}. `
               + `It should take 2 minutes to read it out loud.`
 });

 // Send a first Chat message to summarize what will be done
 await chatClient.spaces.messages.create({
   parent: spaceName,
   requestBody: { text: `Sure, let me work on generating a short story `
                           + `about a ${userMessage} like you requested.`}
 });

 // Go through the response chunks received from the stream
 let messageName = undefined;
 let answer = "";
 for await (const chunk of aiResponse) {
   const text = chunk.text;
   if (text) {
     // Update the answer by concatenating the response chunks
     answer += text;
     // The Chat message request body is the same for message creation and update
     const responseBody = {
       text: answer,
       accessoryWidgets: [getStatusAccessoryWidget('Generating story...', 'progress_activity')]
     }
     if (!messageName) {
       // Create a Chat message dedicated to the generated content
       const messageResponse = await chatClient.spaces.messages.create({
         parent: spaceName,
         requestBody: responseBody
       });
       messageName = messageResponse.data.name;
     } else {
       // Update the Chat message dedicated to the generated content
       await chatClient.spaces.messages.patch({
         name: messageName,
         updateMask: 'text,accessory_widgets',
         requestBody: responseBody
       });
     }
   }
 }

 // Update the accessory widget with final progress status
 await chatClient.spaces.messages.patch({
   name: messageName,
   updateMask: 'accessory_widgets',
   requestBody: {
     accessoryWidgets: [getStatusAccessoryWidget('Story is fully generated', 'check')]
   }
 });

 // Send a last Chat message to confirm it's done
 return res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
   text: 'All done, I hope you like it!'
 }}}}});
});

// Create an accessory widget with progress status
function getStatusAccessoryWidget(text, icon) {
 return { buttonList: { buttons: [{
   text: text,
   icon: { materialIcon: { name: icon}},
   // This is a workaround to have the icon shown, it's not clickable
   onClick: { openLink: { url: "https://google.com"}},
   disabled: true
 }]}};
}

package.json

...
"dependencies": {
  ...
   "google-auth-library": "^10.3.0"
},
...

Cập nhật hàm Google Cloud Run Node.js

  1. Trong môi trường phát triển cục bộ, hãy thay đổi thư mục hiện tại thành node/chat/gen-ai-apps/7-stream. Thư mục này chứa toàn bộ mã nguồn và tài nguyên.
  2. Chuyển đến thẻ Nguồn trên trang thông tin chi tiết về dịch vụ hàm Google Cloud Run.

  1. Nhấp vào Chỉnh sửa nguồn.
  2. Thay thế toàn bộ nội dung của tệp index.jspackage.json bằng nội dung trong môi trường phát triển cục bộ.
  3. Nhấp vào Lưu và triển khai lại.
  4. Chờ quá trình triển khai bản sửa đổi hoàn tất.

487b64f2d3b1a104.png

Thử nào

Trong không gian tin nhắn trực tiếp có ứng dụng Chat trong Google Chat, hãy nhập turtle rồi nhấn enter. Ứng dụng sẽ trả lời bằng một thông báo xác nhận, câu chuyện được tạo có trạng thái là đang tiến hành và một thông báo xác nhận hoàn tất.

17600cd1490972c7.png

26af4b3d442712a5.png

10. Ứng dụng đa phương thức

Ứng dụng này dựa vào một mô hình để chỉnh sửa hình ảnh dựa trên hướng dẫn bằng văn bản của người dùng. Cả người dùng và ứng dụng đều thêm hình ảnh của mình dưới dạng tệp đính kèm trong tin nhắn trên Google Chat để trao đổi. Ứng dụng này dựa vào Google Chat API để tải xuống và tải lên hình ảnh theo phương pháp có lập trình.

Xem lại các khái niệm

Tệp đính kèm trong tin nhắn trên Google Chat

Tệp đính kèm trong tin nhắn trên Google Chat là những tệp (chẳng hạn như hình ảnh hoặc video) được tải lên một tin nhắn trên Google Chat. Bạn có thể quản lý các tệp đính kèm này theo phương thức lập trình, cho phép các ứng dụng tương tác trực tiếp với nội dung đa phương tiện trong các cuộc trò chuyện.

Uỷ quyền trên toàn miền (DWD)

Uỷ quyền trên toàn miền (DWD) cho phép một tài khoản dịch vụ mạo danh người dùng trong một miền Google Workspace, cho phép các ứng dụng thay mặt những người dùng đó thực hiện hành động mà không cần được uỷ quyền trực tiếp. Điều này hữu ích cho những ứng dụng cần truy cập vào dữ liệu người dùng hoặc thực hiện các hành động (chẳng hạn như tải tệp đính kèm lên Google Chat) trong bối cảnh của người dùng, ngay cả khi người dùng không hoạt động, bằng cách cấp cho tài khoản dịch vụ quyền truy cập rộng rãi trên toàn miền.

Quy trình xem xét

74295b25761f1682.png

Xem xét mã nguồn

env.js

...
// Replace with the Gemini model to use.
model: process.env.MODEL || 'gemini-2.0-flash-preview-image-generation',
...

index.js

...
// Import byte stream management libraries.
import { Buffer } from 'buffer';
import { Readable } from 'stream';
...
// Download a Google Chat attachment as base 64 string.
async function downloadFile(appChatClient, attachmentName) {
 const response = await appChatClient.media.download({
     resourceName: attachmentName,
     alt: 'media'
   }, {
     responseType: 'stream'
 });
 const chunks = [];
 return new Promise((resolve) => {
   response.data.on('data', (chunk) => {
     chunks.push(chunk);
   });
   response.data.on('end', () => {
     const fileBuffer = Buffer.concat(chunks);
     const base64String = fileBuffer.toString('base64');
     resolve(base64String);
   });
 });
}

// Upload a base 64 string as Google Chat attachment of a space.
async function uploadFile(useChatClient, spaceName, data) {
 const filename = 'generated_image.png';
 return await userChatClient.media.upload({
   parent: spaceName,
   requestBody: { filename: filename },
   media: {
     mimeType: 'image/png',
     body: Readable.from(Buffer.from(data, 'base64'))
   }
 });
}
...
...
http('gen-ai-app', async (req, res) => {
 const userEmail = req.body.chat.user.email;
 const spaceName = req.body.chat.messagePayload.space.name;
 const userMessage = req.body.chat.messagePayload.message.text;
 const attachmentName = req.body.chat.messagePayload.message.attachment[0].attachmentDataRef.resourceName;
 const attachmentContentType = req.body.chat.messagePayload.message.attachment[0].contentType;

 // Set up app authentication used to download the attachment input
 // Application Default Credentials (ADC) will use the Cloud Run function's
 // default service account.
 const appAuth = new GoogleAuth({
   // Specify the Chat API app authentication scopes
   scopes: ['https://www.googleapis.com/auth/chat.bot']
 });
 // Create Chat service client with application credentials
 const appChatClient = google.chat({
   version: 'v1',
   auth: await appAuth.getClient()
 });

 // Send a request to generate the answer with both text and image contents
 const aiResponse = await genAI.models.generateContent({
   model: env.model,
   contents: [{
     role: 'USER',
     parts: [
       // The text content of the message
       { text: userMessage },
       // The attachment of the message is downloaded and added inline
       { inlineData: {
         data: await downloadFile(appChatClient, attachmentName),
         mimeType: attachmentContentType
       }}
     ]
   }],
   config: { responseModalities: ['TEXT', 'IMAGE']}
 });

 // Set up user impersonation authentication used to upload the attachment output
 // and send the response.
 const impersonatedUserAuth = new GoogleAuth({
   // Specify the Chat API user authentication scopes
   scopes: ['https://www.googleapis.com/auth/chat.messages'],
   keyFile: './credentials.json',
   clientOptions: {
     // Impersonate the user who sent the original message
     subject: userEmail
   }
 });
 // Create Chat service client with impersonated user credentials
 const userChatClient = google.chat({
   version: 'v1',
   auth: await impersonatedUserAuth.getClient()
 });

 let responseText = undefined;
 let responseAttachment = undefined;
 // Go through the response parts received
 for (const part of aiResponse.candidates[0].content.parts) {
   if (part.inlineData) {
     // The resulting image is retrieved inline and uploaded
     const mediaResponse = await uploadFile(userChatClient, spaceName, part.inlineData.data);
     responseAttachment = mediaResponse.data;
   } else {
     responseText = part.text;
   }
 }

 // Create a Chat message dedicated to the generated content
 await userChatClient.spaces.messages.create({
   parent: spaceName,
   requestBody: {
     text: responseText ? responseText : 'Here it is!',
     // The uploaded image is referenced as attachment
     attachment: responseAttachment ? [responseAttachment] : undefined
   }
 });

 // Send a last Chat message to confirm it's done
 return res.send({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
   text: 'Done, feel free to let me know if you need anything else!'
 }}}}});
});
...

Định cấu hình tài khoản dịch vụ và xuất khoá riêng tư

  1. Uỷ quyền cho tài khoản dịch vụ mặc định của Cloud Run quản lý tin nhắn Google Chat cho người dùng. Làm theo hướng dẫn với phạm vi https://www.googleapis.com/auth/chat.messages. Để truy xuất Mã ứng dụng khách của tài khoản dịch vụ mặc định Cloud Run, hãy làm theo các bước sau:
  2. Nhấp vào Trình đơn ☰ > IAM và Quản trị > Tài khoản dịch vụ

  1. Nhấp vào tài khoản dịch vụ có tên Tài khoản dịch vụ mặc định của Compute Engine.
  2. Mở rộng mục Cài đặt nâng cao
  3. Sao chép Mã ứng dụng vào bảng nhớ tạm.
  4. Tạo và tải khoá riêng tư mới xuống cho tài khoản dịch vụ mặc định của Cloud Run
  5. Nhấp vào Trình đơn ☰ > IAM và Quản trị > Tài khoản dịch vụ

  1. Nhấp vào tài khoản dịch vụ có tên Tài khoản dịch vụ mặc định của Compute Engine.
  2. Chọn thẻ Khoá, nhấp vào Thêm khoá, rồi nhấp vào Tạo khoá mới.
  3. Chọn JSON, rồi nhấp vào Tạo.
  4. Cặp khoá công khai/riêng tư mới của bạn sẽ được tạo và tải xuống máy của bạn dưới dạng một tệp mới. Lưu tệp JSON đã tải xuống và sao chép nội dung của tệp đó vào bảng nhớ tạm. Tệp này là bản sao duy nhất của khoá này. Để biết thông tin về cách lưu trữ khoá một cách an toàn, hãy xem phần Quản lý khoá tài khoản dịch vụ.

Cập nhật hàm Google Cloud Run Node.js

  1. Trong môi trường phát triển cục bộ, hãy thay đổi thư mục hiện tại thành node/chat/gen-ai-apps/8-multimodal. Thư mục này chứa toàn bộ mã nguồn và tài nguyên.
  2. Chuyển đến thẻ Nguồn trên trang thông tin chi tiết về dịch vụ hàm Google Cloud Run.

  1. Nhấp vào Chỉnh sửa nguồn.
  2. Nhấp vào , nhập credentials.json rồi nhấp vào ✔️ để tạo tệp tài nguyên bị thiếu.
  3. Dán nội dung của tệp JSON đã tải xuống ở bước trước vào tệp credentials.json vừa tạo.
  4. Thay thế toàn bộ nội dung của tệp index.js bằng nội dung trong môi trường phát triển cục bộ.
  5. Mở tệp env.js rồi đặt giá trị của model thành gemini-2.0-flash-preview-image-generation.
...
model: 'gemini-2.0-flash-preview-image-generation',
...
  1. Nhấp vào Lưu và triển khai lại.
  2. Chờ quá trình triển khai bản sửa đổi hoàn tất.

487b64f2d3b1a104.png

Dùng thử

Trong không gian nhắn tin trực tiếp với ứng dụng Chat trong Google Chat, hãy tải ảnh chân dung của bạn lên ở định dạng PNG, nhập Change the background color to blue rồi nhấn enter. Ứng dụng sẽ trả lời bằng một phiên bản của bức ảnh có nền màu xanh dương và thông báo xác nhận hoàn tất.

270547e7a83c1841.png

11. Dọn dẹp

Xoá dự án trên Google Cloud

Để tránh phát sinh phí cho Tài khoản Google Cloud của bạn đối với các tài nguyên được dùng trong lớp học lập trình này, bạn nên xoá dự án trên Google Cloud.

Trong Bảng điều khiển Google Cloud, hãy làm theo các bước sau:

  1. Nhấp vào Trình đơn ☰ > IAM và Quản trị > Cài đặt.

  1. Nhấp vào Tắt.
  2. Nhập mã dự án.
  3. Nhấp vào Vẫn tắt.

407699a4e03afea6.png

12. Xin chúc mừng

Xin chúc mừng! Bạn đã tạo các ứng dụng Google Chat dưới dạng tiện ích bổ sung của Google Workspace, tích hợp các khái niệm cơ bản về AI!

Tiếp theo là gì?

Chúng tôi chỉ giới thiệu các trường hợp sử dụng tối giản trong lớp học lập trình này, nhưng có rất nhiều lĩnh vực mở rộng mà bạn có thể cân nhắc trong các ứng dụng Google Chat của mình, chẳng hạn như:

  • Hỗ trợ các loại nội dung nghe nhìn khác như âm thanh và video.
  • Tích hợp với các mô hình AI khác, bao gồm cả mô hình tuỳ chỉnh, được lưu trữ trong các nền tảng chuyên dụng như Vertex AI.
  • Tích hợp với các tác nhân, bao gồm cả tác nhân tuỳ chỉnh, được lưu trữ trong các nền tảng chuyên dụng như Agentspace và Dialogflow CX.
  • Dựa vào các vòng phản hồi và phân loại để theo dõi và cải thiện hiệu suất.
  • Xuất bản trên trang web thương mại để hỗ trợ các nhóm, tổ chức hoặc người dùng công khai.

Tìm hiểu thêm

Có rất nhiều tài nguyên dành cho nhà phát triển, chẳng hạn như video trên YouTube, trang web tài liệu, mã mẫu và hướng dẫn: