간단한 REST API를 사용하여 정적 카드를 삽입, 업데이트, 읽기, 삭제할 수 있습니다. 또한 위치 또는 미디어와 같은 객체를 정적 카드에 연결할 수 있습니다.
작동 방식
정적 카드는 기본적으로 Glass 시계 오른쪽에 있으며 게재 시점에 사용자와 관련된 정보를 표시합니다. 그러나 실시간 카드와 같이 즉각적인 주의가 필요하지 않으며 실시간 카드 사용자는 자유롭게 카드를 읽거나 조치를 취할 수 있습니다.

Glassware가 타임라인에 정적 카드를 삽입하면 Glass에서 알림음을 재생하여 사용자에게 알릴 수 있습니다. 이전의 모든 정적 카드도 오른쪽으로 이동하고 7일 후 또는 200개의 카드가 더 새로운 경우 타임라인에서 사라집니다.
용도
정적 카드는 중요한 일이 발생할 때 사용자에게 주기적인 알림을 전달하는 데 유용합니다.
예를 들어 주요 뉴스 기사가 발생할 때 전송하는 뉴스 전달 서비스가 있습니다. Mirror API 정적 카드
는 실시간 카드 또는
몰입형 환경을
OPEN_URI
메뉴 항목을 통해 시작할 수도 있습니다. 이를 통해 정적 카드를 알림으로 사용하고 실시간 카드 또는 몰입형 환경을 사용하여 보다 대화형 환경을 제공하는 하이브리드 상호작용을 만들 수 있습니다.
타임라인 항목에 사용할 수 있는 작업의 전체 목록은 참조 문서를 확인하세요.
정적 카드 삽입
정적 카드 (타임라인 항목)를 삽입하려면 타임라인 항목의 JSON 표현을 REST 엔드포인트에 POST합니다.
타임라인 항목의 대부분의 필드는 선택사항입니다. 가장 간단한 형태의 경우 타임라인 항목에는 이 예와 같이 짧은 문자 메시지만 포함됩니다.
원시 HTTP
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" }
자바
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()
성공하면 생성된 항목의 전체 사본이 포함된 201 Created 응답 코드가 수신됩니다. 이전 예의 경우 성공적인 응답은 다음과 같습니다.
원시 HTTP
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"
}
사용자의 타임라인에 표시되는 삽입된 항목은 다음과 같습니다.

첨부파일이 있는 타임라인 항목 삽입
사진 한 장이 천 마디 말보다 낫습니다. 이는 타임라인 항목에 맞출 수 있는 것보다 훨씬 많은 양입니다. 이를 위해 타임라인 항목에 이미지와 동영상을 첨부할 수도 있습니다. 다음은 사진 첨부파일이 있는 타임라인 항목을 삽입하는 방법을 보여주는 예입니다.
원시 HTTP
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--
자바
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()
첨부된 이미지가 있는 타임라인 항목은 Glass에서 다음과 같이 표시됩니다.

동영상 첨부
타임라인 항목에 동영상 파일을 첨부하는 경우 전체 페이로드를 한 번에 업로드하는 대신 동영상을 스트리밍하는 것이 좋습니다. Google Mirror API는 HTTP 실시간 스트리밍, 프로그레시브 다운로드, 실시간 스트리밍 프로토콜 (RTSP)을 통한 스트리밍을 지원합니다. RTSP는 방화벽에 의해 자주 차단되므로 가능한 경우 다른 옵션을 사용하세요.
동영상을 스트리밍하려면 PLAY_VIDEO
기본 제공 메뉴 항목을 사용하고 동영상의 URL을 메뉴 항목의
payload로 지정합니다. 자세한 내용은
기본 제공 메뉴 항목 추가 및
지원되는 미디어 형식
을 참고하세요.
페이지 나누기
단일 타임라인 카드에 맞지 않지만 동일한 카드와 연결되어야 하는 타임라인 항목을 페이지로 나눌 수 있습니다. 페이지로 나눈
항목은 모두 동일한 timeline.id를 공유하므로 동일한 메뉴 항목 집합을 갖습니다. 사용자가 페이지로 나눈 타임라인 항목을 탭하면 자세히 보기 메뉴 항목이 표시됩니다.
Glass는
text를 표시하는 타임라인 항목을 자동으로 페이지로 나눕니다. Glass에서 자동으로
페이지로 나누도록 하려면 html 다음 예와 같이 클래스 속성이 auto-paginate로 설정된 article
태그를 사용하세요.
<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>
수동으로 페이지를 나누려면 각 카드에 표시할 콘텐츠에 article 태그를 사용하세요. Glass는 각 article 태그의 콘텐츠를 별도의 하위 타임라인 카드에 표시합니다. 예를 들어 다음 HTML을 사용하여 페이지로 나눈 타임라인 항목을 만들 수 있습니다.
<article>
<section>
<p>First page</p>
</section>
</article>
<article>
<section>
<p>Second page</p>
</section>
</article>
<article>
<section>
<p>Third page</p>
</section>
</article>
기본적으로 페이지로 나눈 타임라인 항목의 첫 번째 카드는 표지 카드로 표시되며 사용자가 자세히 보기 메뉴 항목을 선택하면 다시 표시됩니다. **자세히 보기** 를 탭한 후 첫 번째 카드가 다시 표시되지 않도록 하려면 첫 번째 cover-only 태그에 <article> CSS 클래스를 지정하면 됩니다.
<article class="cover-only">
...
cover-only 클래스는 자동으로 페이지로 나눈 타임라인 항목도 지원합니다.
<article class="auto-paginate cover-only">
...
번들로 묶기
번들로 묶기를 사용하면 이메일 스레드의 개별 메시지와 같이 관련이 있지만 서로 다른 항목을 함께 그룹화할 수 있습니다. 번들에는 사용자가 탭하여 번들에 있는 다른 카드가 포함된 하위 타임라인을 표시하는 기본 표지 카드가 있습니다. 번들은 번들 표지 카드의 오른쪽 상단에 있는 접힌 모서리로 일반 타임라인 카드와 구분됩니다.
타임라인 항목을 번들로 묶으려면
bundleId에 동일한 값을 사용하여 만듭니다. 가장 최근에 추가된 항목이 번들의 표지 카드입니다.
다음 이미지는 오른쪽 상단에 접힌 모서리가 있는 번들 표지 카드와 그 아래에 번들로 묶인 카드 두 개를 보여줍니다.


타임라인 항목 읽기
서비스는 생성한 모든 타임라인 항목과 공유된 모든 타임라인 항목에 액세스할 수 있습니다. 다음은 서비스에 표시되는 타임라인 항목을 나열하는 방법입니다.
원시 HTTP
GET /mirror/v1/timeline HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
자바
TimelineItem timelineItem = new TimelineItem();
service.timeline().list().execute();
Python
service.timeline().list().execute()
다른 REST 작업을 사용하여 가져오고, 업데이트하고 및 삭제할 수 있습니다.
첨부파일 액세스
attachments라는 배열 속성을 통해 타임라인 항목의 첨부파일에 액세스할 수 있습니다.
그런 다음 첨부파일의
contentUrl
속성 또는
첨부파일 엔드포인트를 통해 첨부파일의 바이너리 데이터를 가져올 수 있습니다.
원시 HTTP
GET /mirror/v1/timeline/{itemId}/attachments/{attachmentId} HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer {auth token}
자바
TimelineItem item = service.timeline().get(itemId).execute();
String attachmentId = item.getAttachments().get(0).getId();
service.attachments().get(itemId, attachmentId).executeAsInputStream();
메뉴 항목 만들기
메뉴 항목을 사용하면 사용자가 타임라인 카드와 관련된 작업을 요청할 수 있으며 기본 제공 메뉴 항목과 맞춤 메뉴 항목의 두 가지 유형이 있습니다.
기본 제공 메뉴 항목은 타임라인 카드 크게 읽기, 위치로 이동, 이미지 공유, 메시지에 답장과 같이 Glass에서 제공하는 특수 기능에 대한 액세스를 제공합니다.

맞춤 메뉴 항목을 사용하면 애플리케이션에서 Glassware에 특정한 동작을 노출할 수 있으며 브랜딩에 맞는 메뉴 항목 아이콘을 제공할 수도 있습니다.
기본 제공 메뉴 항목 추가
기본 제공 메뉴 항목을 삽입할 때
menuItems array를 채워 타임라인 항목에 추가할 수 있습니다.
기본 제공 메뉴 항목을 사용하려면 각 menuItem의
action만 채우면 됩니다.
원시 HTTP
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"
}
]
}
맞춤 메뉴 항목 정의
기본 제공 메뉴 항목이 적합하지 않은 경우 타임라인 항목을 삽입하거나 업데이트할 때 다음을 수행하여 자체 작업으로 맞춤 메뉴 항목을 만들 수 있습니다.
menuItem.action에CUSTOM을 지정합니다.menuItem.id를 지정합니다. 사용자가 맞춤 메뉴 항목을 탭하면 Glassware에서menuItem.id가 채워진 알림을 수신합니다. 이를 통해 알림의 소스를 확인할 수 있습니다.menuItem.values를 지정하여 Glass에 표시되는iconUrl및displayName을 추가합니다.iconUrl의 경우 배경이 투명한 흰색 50x50 PNG 이미지를 가리킵니다.displayTime을 지정합니다.displayTime을 지정하지 않으면 사용자가 맞춤 메뉴 항목을 탭할 때마다 타임라인 항목이 타임라인의 맨 앞으로 이동합니다.
원시 HTTP
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"
}]
}
]
}
사용자가 타임라인 카드를 고정하도록 허용
사용자가 타임라인 카드를 고정할 수 있는 메뉴 항목을 만들 수 있습니다. 이렇게 하면 타임라인 카드가 기본 시계 카드의 왼쪽에 영구적으로 표시됩니다. 사용자는 동일한 메뉴 항목을 사용하여 카드를 고정 해제할 수도 있습니다.
고정 메뉴 항목은 기본 제공 메뉴 항목이므로 TOGGLE_PINNED
action을(를) menuItem에 제공하기만 하면 됩니다.
원시 HTTP
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"
}
...
]
}
구독
Mirror API를 사용하면 사용자가 알림을 구독 하여 타임라인 항목에서 특정 작업을 수행하거나 사용자 위치 가 업데이트될 때 전송되도록 할 수 있습니다. 알림을 구독할 때 알림을 처리하는 콜백 URL을 제공합니다.
알림 수신
Mirror API의 알림은 JSON 요청 본문이 포함된 구독된 엔드포인트에 POST 요청으로 전송됩니다.
원시 HTTP
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "UPDATE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "<TYPE>",
"payload": "<PAYLOAD>"
}
]
}
자바
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)
오류가 발생하지 않은 경우 서비스는 200 OK HTTP 상태 코드로 API에 응답해야 합니다.
서비스가 오류 코드로 응답하면 Mirror API가 서비스에 알림을 다시 전송하려고 시도할 수 있습니다.
알림 유형
Mirror API는 이벤트마다 다른 알림 페이로드를 전송합니다.
답장
사용자가 기본 제공 REPLY 메뉴 항목을 사용하여 타임라인 항목에 답장했습니다.
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "INSERT",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "REPLY"
}
]
}
itemId 속성은 다음이 포함된 항목의 ID로 설정됩니다.
inReplyTo속성은 답장할 타임라인 항목의ID로 설정됩니다.text속성은 텍스트 트랜스크립션으로 설정됩니다.recipients속성은 답장할 타임라인 항목의creator로 설정됩니다(있는 경우).
예:
{
"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"
]
}
]
}
삭제
사용자가 타임라인 항목을 삭제했습니다.
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "DELETE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer",
"userActions": [
{
"type": "DELETE"
}
]
}
itemId 속성은 삭제된
항목의 ID로 설정됩니다. 항목에는 더 이상 ID 및
isDeleted 속성 이외의 메타데이터가 포함되지 않습니다.
맞춤 메뉴 항목 선택됨
사용자가 서비스에서 설정한 맞춤 메뉴 항목 을 선택했습니다.
{
"collection": "timeline",
"itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
"operation": "UPDATE",
"userToken": "harold_penguin",
"userActions": [
{
"type": "CUSTOM",
"payload": "PING"
}
]
}
itemId 속성은 사용자가 선택한 메뉴 항목의 ID로 설정됩니다.
userActions 배열에는 사용자가 이 항목에서 취한 맞춤 작업 목록이 포함되어 있습니다. 서비스는 이러한 작업을 적절하게 처리해야 합니다.
위치 업데이트
현재 사용자가 새 위치를 사용할 수 있습니다.
{
"collection": "locations",
"itemId": "latest",
"operation": "UPDATE",
"userToken": "harold_penguin",
"verifyToken": "random_hash_to_verify_referer"
}
Glassware가 위치 업데이트를 수신하면 glass.locations.get 엔드포인트에 요청을 전송하여 마지막으로 알려진 위치를 검색합니다. Glassware는 10분마다 위치 업데이트를 수신합니다.
음성 명령
사용자가 음성 명령을 활성화했습니다(예: 'Ok Glass, take a note, Cat Stream, Chipotle's birthday is tomorrow'). 다음 알림이 Glassware로 전송됩니다.
{
"collection": "timeline",
"operation": "INSERT",
"userToken": "chipotle's_owner",
"verifyToken": "mew mew mew",
"itemId": "<ITEM_ID>",
"userActions": [
{“type”: "LAUNCH"}
]
}
이 알림은 LAUNCH 값
userActions 속성으로 다른 알림과 구분됩니다.
그런 다음 itemId의 값을 사용하여 타임라인 항목을 가져올 수 있습니다.
{
"id": "<ITEM_ID>",
"text": "Chipotle's birthday is tomorrow",
"recipients": [
{"id": "CAT_STREAM"}
]
}
recipients 속성에는 사용된 음성 명령을 나타내는 연락처의 id가 포함되어 있습니다.