1. Tổng quan
Trong lớp học lập trình này, bạn sẽ sử dụng Google Apps Script để viết một Tiện ích bổ sung Google Workspace cho Gmail. Tiện ích này cho phép người dùng thêm dữ liệu biên nhận từ email vào bảng tính ngay trong Gmail. Khi người dùng nhận được biên nhận qua email, họ sẽ mở tiện ích bổ sung này. Tiện ích bổ sung sẽ tự động lấy thông tin chi phí có liên quan từ email. Người dùng có thể chỉnh sửa thông tin chi phí rồi gửi để ghi lại chi phí vào bảng tính Google Trang tính.
Kiến thức bạn sẽ học được
- Tạo tiện ích bổ sung của Google Workspace cho Gmail bằng Google Apps Script
- Phân tích cú pháp email bằng Google Apps Script
- Tương tác với Google Trang tính thông qua Google Apps Script
- Lưu trữ các giá trị của người dùng bằng dịch vụ Thuộc tính của Google Apps Script
Bạn cần có
- Có quyền truy cập vào Internet và trình duyệt web
- Tài khoản Google
- Một số thư, tốt nhất là biên nhận qua email, trong Gmail
2. Nhận mã mẫu
Khi tham gia lớp học lập trình này, bạn nên tham khảo phiên bản hoạt động của mã mà bạn sẽ viết. Kho lưu trữ GitHub chứa mã mẫu mà bạn có thể dùng làm tài liệu tham khảo.
Để lấy mã mẫu, hãy chạy lệnh sau qua dòng lệnh:
git clone https://github.com/googleworkspace/gmail-add-on-codelab.git
3. Tạo một tiện ích bổ sung cơ bản
Bắt đầu bằng cách viết mã cho một phiên bản đơn giản của tiện ích bổ sung hiển thị biểu mẫu chi phí cùng với email.
Trước tiên, hãy tạo một dự án Apps Script mới rồi mở tệp kê khai của dự án đó.
- Truy cập vào script.google.com. Tại đây, bạn có thể tạo, quản lý và giám sát các dự án Apps Script.
- Để tạo một dự án mới, ở trên cùng bên trái, hãy nhấp vào Dự án mới. Dự án mới sẽ mở ra cùng với một tệp mặc định có tên là
Code.gs. Tạm thời bỏ quaCode.gs, bạn sẽ làm việc với nó sau. - Nhấp vào Dự án chưa có tên, đặt tên cho dự án là Expense It! rồi nhấp vào Đổi tên.
- Ở bên trái, hãy nhấp vào Cài đặt dự án
. - Chọn hộp đánh dấu Hiển thị tệp kê khai "appscript.json" trong trình chỉnh sửa".
- Nhấp vào Trình chỉnh sửa
. - Để mở tệp kê khai, hãy nhấp vào biểu tượng
appscript.jsonở bên trái.
Trong appscript.json, hãy chỉ định siêu dữ liệu liên kết với tiện ích bổ sung, chẳng hạn như tên và các quyền mà tiện ích bổ sung đó yêu cầu. Thay thế nội dung của appsscript.json bằng các chế độ cài đặt cấu hình sau:
{
"timeZone": "GMT",
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute"
],
"gmail": {
"name": "Expense It!",
"logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/receipt_black_24dp.png",
"contextualTriggers": [{
"unconditional": {
},
"onTriggerFunction": "getContextualAddOn"
}],
"primaryColor": "#41f470",
"secondaryColor": "#94f441"
}
}
Đặc biệt chú ý đến phần của tệp kê khai có tên là contextualTriggers. Phần này của tệp kê khai xác định hàm do người dùng xác định cần gọi khi tiện ích bổ sung được kích hoạt lần đầu tiên. Trong trường hợp này, phương thức này sẽ gọi getContextualAddOn, lấy thông tin chi tiết về email đã mở và trả về một nhóm thẻ để hiển thị cho người dùng.
Để tạo hàm getContextualAddOn, hãy làm theo các bước sau:
- Ở bên trái, hãy di chuyển con trỏ lên biểu tượng
Code.gs, sau đó nhấp vào biểu tượng Trình đơn
> Đổi tên. - Nhập
GetContextualAddOnrồi nhấn phímEnter. Apps Script tự động thêm.gsvào tên tệp, nên bạn không cần nhập đuôi tệp. Nếu bạn nhậpGetContextualAddOn.gs, thì Apps Script sẽ đặt tên cho tệp của bạn làGetContextualAddOn.gs.gs. - Trong
GetContextualAddOn.gs, hãy thay thế mã mặc định bằng hàmgetContextualAddOn:
/**
* Returns the contextual add-on data that should be rendered for
* the current e-mail thread. This function satisfies the requirements of
* an 'onTriggerFunction' and is specified in the add-on's manifest.
*
* @param {Object} event Event containing the message ID and other context.
* @returns {Card[]}
*/
function getContextualAddOn(event) {
var card = CardService.newCardBuilder();
card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense'));
var section = CardService.newCardSection();
section.addWidget(CardService.newTextInput()
.setFieldName('Date')
.setTitle('Date'));
section.addWidget(CardService.newTextInput()
.setFieldName('Amount')
.setTitle('Amount'));
section.addWidget(CardService.newTextInput()
.setFieldName('Description')
.setTitle('Description'));
section.addWidget(CardService.newTextInput()
.setFieldName('Spreadsheet URL')
.setTitle('Spreadsheet URL'));
card.addSection(section);
return [card.build()];
}
Giao diện người dùng của mỗi Tiện ích bổ sung Google Workspace bao gồm các thẻ được chia thành một hoặc nhiều phần, mỗi phần chứa các tiện ích có thể hiển thị và nhận thông tin từ người dùng. Hàm getContextualAddOn tạo một thẻ duy nhất để lấy thông tin chi tiết về một khoản chi phí trong email. Thẻ này có một phần chứa các trường nhập văn bản cho dữ liệu liên quan. Hàm này trả về một mảng gồm các thẻ của tiện ích bổ sung. Trong trường hợp này, mảng được trả về chỉ chứa một thẻ.
Trước khi triển khai tiện ích bổ sung Expense It!, bạn cần có một Dự án Google Cloud Platform (GCP). Các dự án Apps Script sử dụng dự án này để quản lý hoạt động uỷ quyền, dịch vụ nâng cao và thông tin chi tiết khác. Để tìm hiểu thêm, hãy truy cập vào Dự án trên Google Cloud Platform.
Để triển khai và chạy tiện ích bổ sung, hãy làm theo các bước sau:
- Mở dự án của bạn trên GCP rồi sao chép số dự án.
- Trong dự án Apps Script, ở bên trái, hãy nhấp vào Cài đặt dự án
. - Trong phần "Dự án trên Google Cloud Platform (GCP)", hãy nhấp vào Thay đổi dự án.
- Nhập số dự án của dự án trên Google Cloud Platform, rồi nhấp vào Đặt dự án.
- Nhấp vào Triển khai > Triển khai thử nghiệm.
- Đảm bảo rằng loại triển khai là Tiện ích bổ sung của Google Workspace. Nếu cần, ở đầu hộp thoại, hãy nhấp vào Bật các loại triển khai
rồi chọn Tiện ích bổ sung Google Workspace làm loại triển khai. - Bên cạnh Ứng dụng: Gmail, hãy nhấp vào Cài đặt.
- Nhấp vào Xong.
Giờ đây, bạn có thể thấy tiện ích bổ sung trong hộp thư đến của mình trên Gmail.
- Trên máy tính, hãy mở Gmail.
- Trên bảng điều khiển bên phải, hãy chọn Expense It! Tiện ích bổ sung
sẽ xuất hiện. Bạn có thể phải nhấp vào biểu tượng Tuỳ chọn khác
để tìm tiện ích này. - Mở một email, tốt nhất là biên nhận có thông tin về các khoản chi tiêu.
- Để mở tiện ích bổ sung này, trong bảng điều khiển bên phải, hãy nhấp vào Expense It!
. - Cấp quyền truy cập cho Expense It! vào Tài khoản Google của bạn bằng cách nhấp vào Uỷ quyền truy cập rồi làm theo lời nhắc.
Tiện ích bổ sung này hiển thị một biểu mẫu đơn giản bên cạnh thư Gmail đang mở. Thành phần này chưa thực hiện bất kỳ chức năng nào khác, nhưng bạn sẽ xây dựng chức năng của thành phần này trong phần tiếp theo.
Để xem các nội dung cập nhật cho tiện ích bổ sung khi tiếp tục thực hiện bài tập này, bạn chỉ cần lưu mã và làm mới Gmail. Bạn không cần triển khai thêm.
4. Truy cập vào email
Thêm mã tìm nạp nội dung email và mô-đun hoá mã để có thêm một chút tổ chức.
Bên cạnh mục Tệp, hãy nhấp vào biểu tượng Thêm
> Tập lệnh rồi tạo một tệp có tên Cards. Tạo một tệp tập lệnh thứ hai có tên là Helpers. Cards.gs tạo thẻ và sử dụng các hàm từ Helpers.gs để điền các trường trong biểu mẫu dựa trên nội dung của email.
Thay thế mã mặc định trong Cards.gs bằng mã này:
var FIELDNAMES = ['Date', 'Amount', 'Description', 'Spreadsheet URL'];
/**
* Creates the main card users see with form inputs to log expenses.
* Form can be prefilled with values.
*
* @param {String[]} opt_prefills Default values for each input field.
* @param {String} opt_status Optional status displayed at top of card.
* @returns {Card}
*/
function createExpensesCard(opt_prefills, opt_status) {
var card = CardService.newCardBuilder();
card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense'));
if (opt_status) {
if (opt_status.indexOf('Error: ') == 0) {
opt_status = '<font color=\'#FF0000\'>' + opt_status + '</font>';
} else {
opt_status = '<font color=\'#228B22\'>' + opt_status + '</font>';
}
var statusSection = CardService.newCardSection();
statusSection.addWidget(CardService.newTextParagraph()
.setText('<b>' + opt_status + '</b>'));
card.addSection(statusSection);
}
var formSection = createFormSection(CardService.newCardSection(),
FIELDNAMES, opt_prefills);
card.addSection(formSection);
return card;
}
/**
* Creates form section to be displayed on card.
*
* @param {CardSection} section The card section to which form items are added.
* @param {String[]} inputNames Names of titles for each input field.
* @param {String[]} opt_prefills Default values for each input field.
* @returns {CardSection}
*/
function createFormSection(section, inputNames, opt_prefills) {
for (var i = 0; i < inputNames.length; i++) {
var widget = CardService.newTextInput()
.setFieldName(inputNames[i])
.setTitle(inputNames[i]);
if (opt_prefills && opt_prefills[i]) {
widget.setValue(opt_prefills[i]);
}
section.addWidget(widget);
}
return section;
}
Hàm createExpensesCard lấy một mảng các giá trị để điền sẵn vào biểu mẫu dưới dạng một đối số không bắt buộc. Hàm này có thể hiển thị một thông báo trạng thái không bắt buộc, có màu đỏ nếu trạng thái bắt đầu bằng "Error:" (Lỗi:) và có màu xanh lục nếu không. Thay vì thêm từng trường vào biểu mẫu theo cách thủ công, một hàm trợ giúp có tên là createFormSection sẽ lặp lại quy trình tạo các tiện ích nhập văn bản, đặt từng giá trị mặc định bằng setValue, rồi thêm các tiện ích vào các phần tương ứng trên thẻ.
Giờ đây, hãy thay thế mã mặc định trong Helpers.gs bằng đoạn mã sau:
/**
* Finds largest dollar amount from email body.
* Returns null if no dollar amount is found.
*
* @param {Message} message An email message.
* @returns {String}
*/
function getLargestAmount(message) {
return 'TODO';
}
/**
* Determines date the email was received.
*
* @param {Message} message An email message.
* @returns {String}
*/
function getReceivedDate(message) {
return 'TODO';
}
/**
* Determines expense description by joining sender name and message subject.
*
* @param {Message} message An email message.
* @returns {String}
*/
function getExpenseDescription(message) {
return 'TODO';
}
/**
* Determines most recent spreadsheet URL.
* Returns null if no URL was previously submitted.
*
* @returns {String}
*/
function getSheetUrl() {
return 'TODO';
}
Các hàm trong Helpers.gs được getContextualAddon gọi để xác định các giá trị được điền sẵn trên biểu mẫu. Hiện tại, các hàm này sẽ chỉ trả về chuỗi "TODO" vì bạn sẽ triển khai logic điền sẵn ở bước sau.
Tiếp theo, hãy cập nhật mã trong GetContextualAddon.gs để mã này tận dụng mã trong Cards.gs và Helpers.gs. Thay thế mã trong GetContextualAddon.gs bằng mã này:
/**
* Copyright 2017 Google Inc.
*
* 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.
*/
/**
* Returns the contextual add-on data that should be rendered for
* the current e-mail thread. This function satisfies the requirements of
* an 'onTriggerFunction' and is specified in the add-on's manifest.
*
* @param {Object} event Event containing the message ID and other context.
* @returns {Card[]}
*/
function getContextualAddOn(event) {
var message = getCurrentMessage(event);
var prefills = [getReceivedDate(message),
getLargestAmount(message),
getExpenseDescription(message),
getSheetUrl()];
var card = createExpensesCard(prefills);
return [card.build()];
}
/**
* Retrieves the current message given an action event object.
* @param {Event} event Action event object
* @return {Message}
*/
function getCurrentMessage(event) {
var accessToken = event.messageMetadata.accessToken;
var messageId = event.messageMetadata.messageId;
GmailApp.setCurrentMessageAccessToken(accessToken);
return GmailApp.getMessageById(messageId);
}
Lưu ý đến hàm getCurrentMessage mới. Hàm này sử dụng sự kiện do Gmail cung cấp để đọc thư mà người dùng hiện đang mở. Để hàm này hoạt động, hãy thêm một phạm vi khác vào tệp kê khai tập lệnh cho phép quyền truy cập chỉ đọc vào thư trong Gmail.
Trong appscript.json, hãy cập nhật oauthScopes để yêu cầu cả phạm vi https://www.googleapis.com/auth/gmail.addons.current.message.readonly.
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://www.googleapis.com/auth/gmail.addons.current.message.readonly"
],
Trong Gmail, hãy chạy tiện ích bổ sung của bạn và cho phép Expense It! xem email. Các trường biểu mẫu hiện được điền sẵn bằng "TODO".
5. Tương tác với Google Trang tính
Tiện ích bổ sung Expense It! có một biểu mẫu để người dùng nhập thông tin chi tiết về một khoản chi phí, nhưng những thông tin chi tiết đó không được gửi đi. Hãy thêm một nút gửi dữ liệu biểu mẫu đến một Trang tính trên Google.
Để thêm một nút, chúng ta sẽ sử dụng lớp ButtonSet. Để tương tác với Google Trang tính, chúng ta sẽ sử dụng dịch vụ Google Trang tính.
Sửa đổi createFormSection để trả về một nút có nhãn "Gửi" trong phần biểu mẫu của thẻ. Hãy làm theo các bước sau:
- Tạo một nút văn bản bằng cách sử dụng
CardService.newTextButton(), gắn nhãn "Gửi" cho nút bằng cách sử dụngCardService.TextButton.setText(). - Thiết kế nút sao cho khi người dùng nhấp vào nút này, thao tác
submitFormsau đây sẽ được gọi thông quaCardService.TextButton.setOnClickAction():
/**
* Logs form inputs into a spreadsheet given by URL from form.
* Then displays edit card.
*
* @param {Event} e An event object containing form inputs and parameters.
* @returns {Card}
*/
function submitForm(e) {
var res = e['formInput'];
try {
FIELDNAMES.forEach(function(fieldName) {
if (! res[fieldName]) {
throw 'incomplete form';
}
});
var sheet = SpreadsheetApp
.openByUrl((res['Spreadsheet URL']))
.getActiveSheet();
sheet.appendRow(objToArray(res, FIELDNAMES.slice(0, FIELDNAMES.length - 1)));
return createExpensesCard(null, 'Logged expense successfully!').build();
}
catch (err) {
if (err == 'Exception: Invalid argument: url') {
err = 'Invalid URL';
res['Spreadsheet URL'] = null;
}
return createExpensesCard(objToArray(res, FIELDNAMES), 'Error: ' + err).build();
}
}
/**
* Returns an array corresponding to the given object and desired ordering of keys.
*
* @param {Object} obj Object whose values will be returned as an array.
* @param {String[]} keys An array of key names in the desired order.
* @returns {Object[]}
*/
function objToArray(obj, keys) {
return keys.map(function(key) {
return obj[key];
});
}
- Tạo một tiện ích nhóm nút bằng
CardService.newButtonSet()và thêm nút văn bản vào nhóm nút bằngCardService.ButtonSet.addButton(). - Thêm tiện ích tập hợp nút vào phần biểu mẫu của thẻ bằng cách sử dụng
CardService.CardSection.addWidget().
Chỉ bằng vài dòng mã, chúng ta có thể mở một bảng tính bằng URL của bảng tính đó, sau đó thêm một hàng dữ liệu vào bảng tính. Xin lưu ý rằng các dữ liệu đầu vào của biểu mẫu sẽ được truyền vào hàm trong sự kiện e và chúng tôi sẽ kiểm tra để đảm bảo rằng người dùng đã cung cấp tất cả các trường. Giả sử không có lỗi xảy ra, chúng ta sẽ tạo một thẻ chi phí trống có trạng thái thuận lợi. Trong trường hợp phát hiện lỗi, chúng tôi sẽ trả về thẻ đã điền ban đầu cùng với thông báo lỗi. Hàm trợ giúp objToArray giúp bạn dễ dàng chuyển đổi các câu trả lời trong biểu mẫu thành một mảng, sau đó có thể được thêm vào bảng tính.
Cuối cùng, hãy cập nhật phần oauthScopes trong appsscript.json rồi yêu cầu lại phạm vi https://www.googleapis.com/auth/spreadsheets. Khi được uỷ quyền, phạm vi này cho phép tiện ích bổ sung đọc và sửa đổi Google Trang tính của người dùng.
"oauthScopes": [
"https://www.googleapis.com/auth/gmail.addons.execute",
"https://www.googleapis.com/auth/gmail.addons.current.message.readonly",
"https://www.googleapis.com/auth/spreadsheets"
],
Nếu chưa tạo bảng tính mới, hãy tạo một bảng tính tại https://docs.google.com/spreadsheets/.
Giờ thì hãy chạy lại tiện ích bổ sung và thử gửi biểu mẫu. Đảm bảo rằng bạn nhập URL đầy đủ của URL đích vào trường biểu mẫu URL của bảng tính.
6. Lưu trữ các giá trị bằng dịch vụ Thuộc tính
Thường thì người dùng sẽ ghi nhiều khoản chi phí vào cùng một bảng tính, vì vậy, sẽ rất thuận tiện nếu bạn cung cấp URL của bảng tính gần đây nhất làm giá trị mặc định trong thẻ. Để biết URL của bảng tính gần đây nhất, chúng ta cần lưu trữ thông tin đó mỗi khi sử dụng tiện ích bổ sung.
Dịch vụ Properties cho phép chúng ta lưu trữ các cặp khoá-giá trị. Trong trường hợp này, một khoá hợp lý sẽ là "SPREADSHEET_URL" trong khi giá trị sẽ là chính URL đó. Để lưu trữ giá trị như vậy, bạn cần sửa đổi submitForm trong Cards.gs sao cho URL của bảng tính được lưu trữ dưới dạng một thuộc tính khi thêm một hàng mới vào trang tính.
Xin lưu ý rằng các thuộc tính có thể có một trong ba phạm vi: tập lệnh, người dùng hoặc tài liệu. Phạm vi tài liệu không áp dụng cho tiện ích bổ sung Gmail, mặc dù phạm vi này có liên quan đến một loại tiện ích bổ sung riêng biệt khi lưu trữ thông tin dành riêng cho một Google Tài liệu hoặc Trang tính cụ thể. Đối với tiện ích bổ sung của chúng tôi, hành vi mong muốn là mỗi cá nhân sẽ thấy bảng tính gần đây nhất của riêng họ (thay vì của người khác) dưới dạng lựa chọn mặc định trên biểu mẫu. Do đó, chúng ta chọn phạm vi người dùng thay vì phạm vi tập lệnh.
Sử dụng PropertiesService.getUserProperties().setProperty() để lưu trữ URL của bảng tính. Thêm nội dung sau vào submitForm trong Cards.gs:
PropertiesService.getUserProperties().setProperty('SPREADSHEET_URL',
res['Spreadsheet URL']);
Sau đó, hãy sửa đổi hàm getSheetUrl trong Helpers.gs để trả về thuộc tính đã lưu trữ sao cho người dùng sẽ thấy URL gần đây nhất mỗi khi họ sử dụng tiện ích bổ sung. Dùng PropertiesService.getUserProperties().getProperty() để lấy giá trị của thuộc tính.
/**
* Determines most recent spreadsheet URL.
* Returns null if no URL was previously submitted.
*
* @returns {String}
*/
function getSheetUrl() {
return PropertiesService.getUserProperties().getProperty('SPREADSHEET_URL');
}
Cuối cùng, để truy cập vào dịch vụ Tài sản, tập lệnh cũng cần được uỷ quyền. Thêm phạm vi https://www.googleapis.com/auth/script.storage vào tệp kê khai như trước để cho phép tiện ích bổ sung đọc và ghi thông tin về tài sản.
7. Phân tích cú pháp thư trên Gmail
Để thực sự tiết kiệm thời gian cho người dùng, hãy điền sẵn thông tin liên quan về khoản chi phí trong email vào biểu mẫu. Chúng ta đã tạo các hàm trong Helpers.gs đóng vai trò này, nhưng cho đến nay, chúng ta chỉ trả về "TODO" cho ngày, số tiền và nội dung mô tả của khoản chi tiêu.
Ví dụ: chúng ta có thể lấy ngày nhận được email và sử dụng ngày đó làm giá trị mặc định cho ngày phát sinh chi phí.
/**
* Determines date the email was received.
*
* @param {Message} message - The message currently open.
* @returns {String}
*/
function getReceivedDate(message) {
return message.getDate().toLocaleDateString();
}
Triển khai 2 hàm còn lại:
getExpenseDescriptioncó thể bao gồm việc kết hợp cả tên người gửi và tiêu đề thư, mặc dù có những cách phức tạp hơn để phân tích cú pháp nội dung thư và cung cấp nội dung mô tả chính xác hơn nữa.- Đối với
getLargestAmount, hãy cân nhắc tìm kiếm các biểu tượng cụ thể liên quan đến tiền. Biên nhận thường có nhiều giá trị được liệt kê, chẳng hạn như thuế và các khoản phí khác. Hãy nghĩ xem bạn có thể xác định số tiền chính xác bằng cách nào. Biểu thức chính quy cũng có thể hữu ích.
Nếu bạn cần thêm cảm hứng, hãy khám phá tài liệu tham khảo về GmailMessage hoặc xem đoạn mã giải pháp mà bạn đã tải xuống khi bắt đầu lớp học lập trình này. Sau khi bạn đã nghĩ ra cách triển khai riêng cho tất cả các hàm trong Helpers.gs, hãy dùng thử tiện ích bổ sung của bạn! Mở biên nhận và bắt đầu ghi lại biên nhận trong bảng tính!
8. Xoá biểu mẫu bằng các thao tác trên thẻ
Điều gì sẽ xảy ra nếu Expense It! xác định nhầm một khoản chi phí trong email đang mở và điền sẵn thông tin không chính xác vào biểu mẫu? Người dùng xoá biểu mẫu. Lớp CardAction cho phép chúng ta chỉ định một hàm được gọi khi người dùng nhấp vào thao tác. Hãy dùng nút này để giúp người dùng xoá biểu mẫu một cách nhanh chóng.
Sửa đổi createExpensesCard sao cho thẻ mà hàm này trả về có một thao tác trên thẻ có nhãn "Xoá biểu mẫu" và khi được nhấp vào sẽ gọi hàm clearForm sau đây. Bạn có thể dán hàm này vào Cards.gs. Bạn sẽ cần truyền opt_status dưới dạng một tham số có tên là "Trạng thái" cho thao tác để đảm bảo rằng thông báo trạng thái vẫn còn khi biểu mẫu bị xoá. Xin lưu ý rằng các tham số không bắt buộc cho các thao tác phải thuộc loại Object.<string, string>, vì vậy, nếu không có opt_status, bạn nên truyền {'Status' : ''}.
/**
* Recreates the main card without prefilled data.
*
* @param {Event} e An event object containing form inputs and parameters.
* @returns {Card}
*/
function clearForm(e) {
return createExpensesCard(null, e['parameters']['Status']).build();
}
9. Tạo bảng tính
Ngoài việc sử dụng Google Apps Script để chỉnh sửa bảng tính hiện có, bạn có thể tạo một bảng tính hoàn toàn mới theo cách lập trình. Đối với tiện ích bổ sung này, hãy cho phép người dùng tạo bảng tính về các khoản chi phí. Để bắt đầu, hãy thêm phần thẻ sau vào thẻ mà createExpensesCard trả về.
var newSheetSection = CardService.newCardSection();
var sheetName = CardService.newTextInput()
.setFieldName('Sheet Name')
.setTitle('Sheet Name');
var createExpensesSheet = CardService.newAction()
.setFunctionName('createExpensesSheet');
var newSheetButton = CardService.newTextButton()
.setText('New Sheet')
.setOnClickAction(createExpensesSheet);
newSheetSection.addWidget(sheetName);
newSheetSection.addWidget(CardService.newButtonSet().addButton(newSheetButton));
card.addSection(newSheetSection);
Giờ đây, khi người dùng nhấp vào nút "Trang tính mới", tiện ích bổ sung sẽ tạo một bảng tính mới được định dạng với một hàng tiêu đề cố định để luôn hiển thị. Người dùng chỉ định tiêu đề cho bảng tính mới trong biểu mẫu, mặc dù việc thêm giá trị mặc định trong trường hợp biểu mẫu trống có thể là một lựa chọn phù hợp. Trong quá trình triển khai createExpensesSheet, hãy trả về một thẻ gần giống với thẻ hiện có, đồng thời thêm một thông báo trạng thái thích hợp cũng như điền sẵn vào trường URL bằng URL của bảng tính mới.
10. Xin chúc mừng!
Bạn đã thiết kế và triển khai thành công một tiện ích bổ sung dành cho Gmail có thể tìm thấy một khoản chi phí trong email và giúp người dùng ghi lại khoản chi phí đó vào bảng tính chỉ trong vài giây. Bạn đã sử dụng Google Apps Script để tương tác với nhiều API của Google và duy trì dữ liệu giữa nhiều lần thực thi tiện ích bổ sung.
Những điểm có thể cải thiện
Hãy để trí tưởng tượng dẫn dắt bạn khi bạn cải thiện Expense It!, nhưng đây là một số ý tưởng để tạo ra một sản phẩm hữu ích hơn nữa:
- Liên kết đến bảng tính sau khi người dùng ghi lại một khoản chi phí
- Thêm khả năng chỉnh sửa/huỷ thao tác ghi nhật ký chi phí
- Tích hợp các API bên ngoài để cho phép người dùng thanh toán và yêu cầu tiền