Bạn có thể chèn, cập nhật, đọc và xóa thẻ tĩnh bằng các API REST đơn giản. Ngoài ra, bạn có thể đính kèm các đối tượng vào thẻ tĩnh, chẳng hạn như vị trí hoặc nội dung nghe nhìn.
Cách hoạt động
Theo mặc định, thẻ tĩnh nằm ở bên phải đồng hồ Glass và hiển thị thông tin liên quan đến người dùng tại thời điểm phân phối. Tuy nhiên, các chức năng này không yêu cầu sự chú ý ngay lập tức như thẻ trực tiếp và người dùng có thể chọn đọc hoặc thao tác trên thẻ khi rảnh.
Khi Glassware chèn thẻ tĩnh vào dòng thời gian, Glass có thể phát âm thanh thông báo để cảnh báo cho người dùng. Tất cả thẻ tĩnh trước đó cũng chuyển sang phải và biến mất khỏi dòng thời gian sau 7 ngày hoặc khi 200 thẻ mới hơn.
Thời điểm nên sử dụng thành phần địa điểm của đơn vị liên kết
Thẻ tĩnh rất phù hợp để gửi thông báo định kỳ cho người dùng khi có những việc quan trọng xảy ra.
Ví dụ: dịch vụ phân phối tin tức gửi tin bài hàng đầu khi chúng xảy ra. Thẻ tĩnh của Mirror API cũng có thể bắt đầu thẻ trực tiếp hoặc được nhúng thông qua mục trong trình đơn OPEN_URI
. Điều này cho phép bạn tạo ra các hoạt động tương tác kết hợp sử dụng thẻ tĩnh làm thông báo và một thẻ trực tiếp hoặc trải nghiệm nhúng để có trải nghiệm tương tác nhiều hơn.
Để biết danh sách đầy đủ các thao tác có thể thực hiện cho các mục tiến trình, hãy xem tài liệu tham khảo.
Chèn thẻ tĩnh
Để chèn thẻ tĩnh (các mục trong dòng thời gian), hãy ĐĂNG bản trình bày JSON của một mục dòng thời gian vào điểm cuối REST.
Hầu hết các trường trong một mục dòng thời gian là không bắt buộc. Ở dạng đơn giản nhất, một mục trên dòng thời gian chỉ chứa một tin nhắn văn bản ngắn, như trong ví dụ sau:
HTTP thô
POST /mirror/v1/timeline HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
Content-Type: application/json
Content-Length: 26
{ "text": "Hello world" }
Java
TimelineItem timelineItem = new TimelineItem();
timelineItem.setText("Hello world");
service.timeline().insert(timelineItem).execute();
Python
timeline_item = {'text': 'Hello world'}
service.timeline().insert(body=timeline_item).execute()
Khi thành công, bạn sẽ nhận được mã phản hồi 201 Created
với bản sao đầy đủ của mục đã tạo. Trong ví dụ trước, phản hồi thành công có thể có dạng như sau:
HTTP thô
HTTP/1.1 201 Created
Date: Tue, 25 Sep 2012 23:30:11 GMT
Content-Type: application/json
Content-Length: 303
{
"kind": "glass#timelineItem",
"id": "1234567890",
"selfLink": "https://www.googleapis.com/mirror/v1/timeline/1234567890",
"created": "2012-09-25T23:28:43.192Z",
"updated": "2012-09-25T23:28:43.192Z",
"etag": "\"G5BI0RWvj-0jWdBrdWrPZV7xPKw/t25selcGS3uDEVT6FB09hAG-QQ\"",
"text": "Hello world"
}
Mục được chèn sẽ xuất hiện trong dòng thời gian của người dùng có dạng như sau:
Chèn một mục dòng thời gian có tệp đính kèm
Một bức ảnh đáng giá một nghìn từ, đủ để bạn có thể vừa với một mục trong dòng thời gian. Để đạt được mục tiêu này, bạn cũng có thể đính kèm hình ảnh và video vào một mục trên dòng thời gian. Sau đây là ví dụ về cách chèn mục trong dòng thời gian có tệp đính kèm là ảnh:
HTTP thô
POST /upload/mirror/v1/timeline HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
Content-Type: multipart/related; boundary="mymultipartboundary"
Content-Length: {length}
--mymultipartboundary
Content-Type: application/json; charset=UTF-8
{ "text": "A solar eclipse of Saturn. Earth is also in this photo. Can you find it?" }
--mymultipartboundary
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
[binary image data]
--mymultipartboundary--
Java
TimelineItem timelineItem = new TimelineItem();
timelineItem.setText("Hello world");
InputStreamContent mediaContent = new InputStreamContent(contentType, attachment);
service.timeline().insert(timelineItem, mediaContent).execute();
Python
timeline_item = {'text': 'Hello world'}
media_body = MediaIoBaseUpload(
io.BytesIO(attachment), mimetype=content_type, resumable=True)
service.timeline().insert(body=timeline_item, media_body=media_body).execute()
Mục dòng thời gian có hình ảnh đính kèm trông giống như sau trên Glass:
Đang đính kèm video
Nếu đang đính kèm tệp video vào các mục trong dòng thời gian, bạn nên phát trực tuyến video thay vì tải toàn bộ trọng tải lên cùng lúc. API Google Mirror hỗ trợ phát trực tuyến bằng tính năng phát trực tiếp HTTP, tải xuống liên tục và giao thức truyền trực tuyến theo thời gian thực (RTSP). RTSP thường bị chặn bởi tường lửa, vì vậy hãy sử dụng các tùy chọn khác khi có thể.
Để phát trực tuyến video, hãy sử dụng mục trong trình đơn tích hợp PLAY_VIDEO
và chỉ định URL của video làm payload
của mục trong trình đơn. Hãy xem phần Thêm các mục trong trình đơn tích hợp sẵn và các định dạng nội dung nghe nhìn được hỗ trợ để biết thêm thông tin.
Phân trang
Bạn có thể phân trang các mục trong dòng thời gian không vừa với một thẻ dòng thời gian, nhưng nên được liên kết với cùng một thẻ. Các mục được phân trang đều có cùng một timeline.id
và do đó có cùng một tập hợp các mục trong trình đơn. Khi người dùng nhấn vào một mục trên dòng thời gian được phân trang, mục trong trình đơn Đọc thêm sẽ xuất hiện.
Glass tự động phân trang các mục theo dòng thời gian hiển thị
text
. Để Glass tự động phân trang html
, hãy sử dụng thẻ article
có thuộc tính lớp được đặt thành auto-paginate
như trong ví dụ sau:
<article class="auto-paginate">
<h3>Very long list</h3>
<ul>
<li>First item</li>
<li>Second item</li>
<li>Third item</li>
<li>Fourth item</li>
<li>Fifth item</li>
<li>Sixth item</li>
<li>...</li>
</ul>
<article>
Để phân trang theo cách thủ công, hãy sử dụng thẻ article
cho nội dung mà bạn muốn hiển thị trên mỗi thẻ. Glass hiển thị nội dung của từng thẻ article
trong một thẻ tiến trình phụ riêng biệt. Ví dụ: bạn có thể tạo một mục dòng thời gian được phân trang bằng HTML sau:
<article>
<section>
<p>First page</p>
</section>
</article>
<article>
<section>
<p>Second page</p>
</section>
</article>
<article>
<section>
<p>Third page</p>
</section>
</article>
Theo mặc định, thẻ đầu tiên của mục trong dòng thời gian được phân trang sẽ hiển thị dưới dạng thẻ bìa và hiển thị lại khi người dùng chọn mục trong trình đơn Đọc thêm. Để thẻ đầu tiên không xuất hiện lại sau khi nhấn vào Đọc thêm, bạn có thể chỉ định lớp CSS cover-only
cho thẻ <article>
đầu tiên:
<article class="cover-only">
...
Lớp cover-only
cũng hỗ trợ các mục trong dòng thời gian được tự động phân trang:
<article class="auto-paginate cover-only">
...
Nhóm
Tính năng nhóm lại cho phép bạn nhóm các mục có liên quan nhưng riêng biệt lại với nhau, chẳng hạn như đối với từng thư riêng lẻ trong một chuỗi email. Gói có một thẻ bìa chính mà người dùng nhấn vào để hiển thị dòng thời gian phụ có chứa các thẻ khác trong gói. Các gói được phân biệt với thẻ dòng thời gian thông thường bằng một nếp gập ở góc trên bên phải thẻ bìa của gói.
Để nhóm các mục trong dòng thời gian, hãy tạo các mục đó có cùng giá trị cho bundleId
. Mục được thêm gần đây nhất là thẻ bìa của gói.
Các hình ảnh sau đây hiển thị một thẻ bìa gói có nếp gập góc ở góc trên cùng bên phải và hai thẻ đi kèm bên dưới.
Đọc mục trong dòng thời gian
Dịch vụ của bạn có thể truy cập vào tất cả các mục dòng thời gian mà dịch vụ đó tạo ra và tất cả các mục trong dòng thời gian được chia sẻ với dịch vụ đó. Đây là cách liệt kê các mục trên dòng thời gian hiển thị cho dịch vụ của bạn.
HTTP thô
GET /mirror/v1/timeline HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
Java
TimelineItem timelineItem = new TimelineItem();
service.timeline().list().execute();
Python
service.timeline().list().execute()
Bạn có thể sử dụng các thao tác REST khác để nhận, cập nhật và xoá các mục trong dòng thời gian.
Truy cập vào tệp đính kèm
Bạn có thể truy cập các tệp đính kèm vào một mục trên dòng thời gian thông qua
một thuộc tính mảng có tên là attachments
.
Sau đó, bạn có thể lấy dữ liệu nhị phân của tệp đính kèm thông qua
thuộc tính contentUrl
của tệp đính kèm hoặc bằng
điểm cuối của tệp đính kèm.
HTTP thô
GET /mirror/v1/timeline/{itemId}/attachments/{attachmentId} HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
Java
TimelineItem item = service.timeline().get(itemId).execute();
String attachmentId = item.getAttachments().get(0).getId();
service.attachments().get(itemId, attachmentId).executeAsInputStream();
Tạo các mục trong trình đơn
Các mục trong trình đơn cho phép người dùng yêu cầu các thao tác liên quan đến thẻ tiến trình và có hai loại: mục trong trình đơn tích hợp sẵn và mục trong trình đơn tuỳ chỉnh.
Các mục trong trình đơn tích hợp sẵn sẽ cung cấp quyền sử dụng các chức năng đặc biệt do Glass cung cấp, chẳng hạn như đọc to thẻ dòng thời gian, di chuyển đến một vị trí, chia sẻ hình ảnh hoặc trả lời một tin nhắn:
Các mục trong trình đơn tuỳ chỉnh cho phép ứng dụng của bạn hiển thị hành vi dành riêng cho Glassware, đồng thời bạn cũng có thể cung cấp biểu tượng mục trong trình đơn để phù hợp với thương hiệu của mình.
Thêm các mục trong trình đơn tích hợp sẵn
Bạn có thể thêm các mục trong trình đơn tích hợp sẵn vào mục dòng thời gian bằng cách điền
menuItems array
khi chèn mục đó.
Để sử dụng một mục trong trình đơn tích hợp sẵn, bạn chỉ cần điền action
của từng menuItem
.
HTTP thô
HTTP/1.1 201 Created
Date: Tue, 25 Sep 2012 23:30:11 GMT
Content-Type: application/json
Content-Length: 303
{
"text": "Hello world",
"menuItems": [
{
"action": "REPLY"
}
]
}
Xác định các mục trong trình đơn tuỳ chỉnh
Nếu các mục trong trình đơn tích hợp sẵn không phù hợp với bạn, bạn có thể tạo các mục trong trình đơn tuỳ chỉnh bằng các thao tác của riêng mình bằng cách làm như sau khi chèn hoặc cập nhật mục dòng thời gian:
- Hãy chỉ định
CUSTOM
chomenuItem.action
. - Hãy chỉ định một
menuItem.id
. Khi người dùng nhấn vào mục trong trình đơn tuỳ chỉnh, Glassware của bạn sẽ nhận được thông báo cómenuItem.id
được điền sẵn. Điều này cho phép bạn xác định nguồn gốc của thông báo. - Chỉ định
menuItem.values
để thêm mộticonUrl
vàdisplayName
xuất hiện trên Glass. Trỏ đến hình ảnh PNG 50 x 50 có màu trắng với nền trong suốt choiconUrl
. Hãy chỉ định một
displayTime
. Nếu bạn không chỉ địnhdisplayTime
, mục dòng thời gian sẽ di chuyển đến trước dòng thời gian khi người dùng nhấn vào mục trong trình đơn tuỳ chỉnh.
HTTP thô
HTTP/1.1 201 Created
Date: Tue, 25 Sep 2012 23:30:11 GMT
Content-Type: application/json
Content-Length: 303
{
"text": "Hello world",
"displayTime": "2013-08-08T22:47:31-07:00",
"menuItems": [
{
"action": "CUSTOM",
"id": "complete"
"values": [{
"displayName": "Complete",
"iconUrl": "http://example.com/icons/complete.png"
}]
}
]
}
Cho phép người dùng ghim thẻ dòng thời gian của bạn
Bạn có thể tạo một mục trong trình đơn cho phép người dùng ghim thẻ dòng thời gian, thẻ này sẽ hiển thị vĩnh viễn thẻ dòng thời gian ở bên trái thẻ đồng hồ chính. Người dùng cũng có thể bỏ ghim thẻ bằng cách sử dụng cùng một mục trong trình đơn.
Mục trong trình đơn ghim là một mục trong trình đơn tích hợp sẵn, vì vậy, bạn chỉ cần cung cấp TOGGLE_PINNED
action
cho menuItem
.
HTTP thô
HTTP/1.1 201 Created
Date: Tue, 25 Sep 2012 23:30:11 GMT
Content-Type: application/json
Content-Length: 303
{
"text": "You can pin or unpin this card.",
"menuItems": [
{
"action": "TOGGLE_PINNED"
}
...
]
}
Gói thuê bao
Mirror API cho phép bạn đăng ký các thông báo được gửi khi người dùng thực hiện hành động cụ thể trên Mục dòng thời gian hoặc khi vị trí người dùng đã được cập nhật. Khi đăng ký một thông báo, bạn sẽ cung cấp một URL gọi lại để xử lý thông báo đó.
Nhận thông báo
Một thông báo từ Mirror API được gửi dưới dạng yêu cầu POST
đến điểm cuối đã đăng ký chứa nội dung yêu cầu JSON
.
HTTP thô
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "UPDATE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "<TYPE>",
"payload": "<PAYLOAD>"
}
]
}
Java
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.mirror.model.Notification;
import java.io.IOException;
import java.io.InputStream;
// ...
public class MyClass {
// ...
/**
* Parse a request body into a Notification object.
*
* @param requestBody The notification payload sent by the Mirror API.
* @return Parsed notification payload if successful, {@code null} otherwise.
*/
static Notification parseNotification(InputStream requestBody) {
try {
JsonFactory jsonFactory = new JacksonFactory();
return jsonFactory.fromInputStream(requetBody, Notification.class);
} catch (IOException e) {
System.out.println("An error occurred: " + e);
return null;
}
}
// ...
}
Python
import json
def parse_notification(request_body):
"""Parse a request body into a notification dict.
Params:
request_body: The notification payload sent by the Mirror API as a string.
Returns:
Dict representing the notification payload.
"""
return json.load(request_body)
Dịch vụ của bạn phải phản hồi API bằng mã trạng thái HTTP 200 OK
nếu không có lỗi xảy ra.
Nếu dịch vụ của bạn phản hồi bằng mã lỗi, API Mirror có thể thử gửi lại thông báo cho dịch vụ của bạn.
Loại thông báo
Mirror API gửi một gói dữ liệu thông báo khác cho các sự kiện khác nhau.
Trả lời
Người dùng đã trả lời mục dòng thời gian của bạn bằng cách sử dụng mục trong trình đơn REPLY
tích hợp:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "INSERT",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "REPLY"
}
]
}
Thuộc tính itemId
được đặt thành ID
của mục có chứa:
- Thuộc tính
inReplyTo
được đặt thànhID
của mục trong dòng thời gian mà mục đó trả lời. - Thuộc tính
text
được đặt thành bản chép lời. - Thuộc tính
recipients
được đặt thànhcreator
của mục trong dòng thời gian mà mục đó trả lời, nếu có.
Ví dụ:
{
"kind": "glass#timelineItem",
"id": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"inReplyTo": "3236e5b0-b282-4e00-9d7b-6b80e2f47f3d",
"text": "This is a text reply",
"recipients": [
{
"id": "CREATOR_ID",
"displayName": "CREATOR_DISPLAY_NAME",
"imageUrls": [
"CREATOR_IMAGE_URL"
]
}
]
}
Xoá
Người dùng đã xoá một mục trong dòng thời gian:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "DELETE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "DELETE"
}
]
}
Thuộc tính itemId
được đặt thành mã nhận dạng của mục đã xoá. Mục này không còn chứa siêu dữ liệu ngoài mã nhận dạng và thuộc tính isDeleted
.
Đã chọn mục tuỳ chỉnh trên trình đơn
Người dùng đã chọn một mục trình đơn tuỳ chỉnh do dịch vụ của bạn đặt:
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "UPDATE",
"userToken": "harold_penguin",
"userActions": [
{
"type": "CUSTOM",
"payload": "PING"
}
]
}
Thuộc tính itemId
được đặt thành mã nhận dạng của mục trong trình đơn mà người dùng đã chọn.
Mảng userActions
chứa danh sách các hành động tuỳ chỉnh mà người dùng đã thực hiện trên mục này. Dịch vụ của bạn sẽ xử lý những thao tác đó cho phù hợp.
Thông tin cập nhật về vị trí
Người dùng hiện tại có thể truy cập vào một vị trí mới:
{
"collection": "locations",
"itemId": "latest",
"operation": "UPDATE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer"
}
Khi Glassware của bạn nhận được thông tin cập nhật về vị trí, hãy gửi yêu cầu đến điểm cuối glass.locations.get để truy xuất vị trí đã biết mới nhất. Glassware của bạn sẽ nhận được thông tin cập nhật vị trí mười phút một lần.
Lệnh thoại
Người dùng đã kích hoạt một lệnh thoại, ví dụ: "Ok Glass, hãy ghi chú, Cat Stream, sinh nhật của Chipotle là ngày mai". Thông báo sau sẽ được gửi tới Glassware của bạn:
{
"collection": "timeline",
"operation": "INSERT",
"userToken": "chipotle's_owner",
"verifyToken": "mew mew mew",
"itemId": "<ITEM_ID>",
"userActions": [
{“type”: "LAUNCH"}
]
}
Thông báo này được phân biệt với các thông báo khác bằng giá trị LAUNCH
trong thuộc tính userActions
.
Sau đó, bạn có thể dùng giá trị trong itemId
để tìm nạp mục dòng thời gian:
{
"id": "<ITEM_ID>",
"text": "Chipotle's birthday is tomorrow",
"recipients": [
{"id": "CAT_STREAM"}
]
}
Thuộc tính recipients
chứa id
của địa chỉ liên hệ đại diện cho lệnh thoại được sử dụng.