Statische Karten

Mit einfachen REST APIs können Sie statische Karten einfügen, aktualisieren, lesen und löschen. Darüber hinaus können Sie Objekte mit einer statischen Karte verknüpfen, z. B. einem Standort oder einem Medium.

Funktionsweise

Statische Karten befinden sich standardmäßig rechts neben der Glass-Uhr und zeigen Informationen an, die zum Zeitpunkt der Lieferung für den Nutzer relevant sind. Sie erfordern jedoch keine sofortige Aufmerksamkeit wie Livekarten und Nutzer können selbst entscheiden, ob sie die Karte lesen oder verwenden möchten.

Wenn Glassware statische Karten in die Zeitachse einfügt, gibt Glass möglicherweise einen Benachrichtigungston aus, um die Nutzer zu warnen. Alle vorherigen statischen Karten werden ebenfalls nach rechts verschoben und verschwinden nach 7 Tagen oder wenn 200 Karten neuer sind.

Verwendung

Statische Karten sind ideal, um Nutzern regelmäßige Benachrichtigungen zu senden, wenn wichtige Ereignisse eintreten. Ein Beispiel: Ein Nachrichtenlieferdienst, der die wichtigsten Nachrichtenmeldungen in Echtzeit sendet. Statische Karten der Mirror API können auch Livekarten oder Unterhaltungen über den Menüpunkt OPEN_URI starten. Auf diese Weise kannst du hybride Interaktionen erstellen, bei denen statische Karten als Benachrichtigungen und eine Live-Karte oder Immersion für eine interaktivere Nutzung verwendet werden.

Eine vollständige Liste der möglichen Vorgänge für Zeitachsenelemente finden Sie in der Referenzdokumentation.

Statische Karten einfügen

POSTEN Sie zum Einfügen statischer Karten (Zeitachsenelemente) eine JSON-Darstellung eines Zeitachsenelements an den REST-Endpunkt.

Die meisten Felder in einem Zeitachsenelement sind optional. In seiner einfachsten Form enthält ein Zeitachsenelement nur eine kurze Textnachricht, wie in diesem Beispiel:

HTTP-Rohdaten

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()

Bei Erfolg erhalten Sie einen 201 Created-Antwortcode mit einer vollständigen Kopie des erstellten Elements. Für das vorherige Beispiel könnte eine erfolgreiche Antwort so aussehen:

HTTP-Rohdaten

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"
}

Das eingefügte Element, das in der Zeitachse des Nutzers erscheinen würde, sieht wie folgt aus:

Zeitachsenelement mit einem Anhang einfügen

Ein Bild sagt mehr als tausend Worte – also weit mehr, als in eine Zeitachse passen würde. Sie können auch Bilder und Videos an ein Zeitachsenelement anhängen. Hier ein Beispiel für das Einfügen eines Zeitachsenelements mit einem Fotoanhang:

HTTP-Rohdaten

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()

Eine Zeitachse mit einem angehängten Bild sieht in Glass in etwa so aus:

Video wird angehängt

Wenn Sie Videodateien an Ihre Zeitachsenelemente anhängen, empfehlen wir, das Video zu streamen, anstatt die gesamte Nutzlast auf einmal hochzuladen. Die Google Mirror API unterstützt Streaming mit HTTP-Livestreaming, Progressive Download und Real Time Streaming Protocol (RTSP). RTSP wird häufig von Firewalls blockiert. Verwenden Sie daher nach Möglichkeit die anderen Optionen.

Verwende zum Streamen von Videos den integrierten Menüpunkt PLAY_VIDEO und gib die Video-URL als payload des Menüelements an. Weitere Informationen finden Sie unter Integrierte Menüelemente hinzufügen und Unterstützte Medienformate.

Paginierung

Sie können Zeitachsenelemente paginieren, die nicht auf eine einzelne Zeitachsenkarte passen, aber ansonsten mit derselben Karte verknüpft sein sollten. Elemente in fortlaufenden Sequenzen haben alle dieselbe timeline.id und daher dieselben Menüelemente. Wenn ein Nutzer auf ein Element in der paginierten Zeitachse tippt, wird der Menüpunkt Weitere Informationen angezeigt.

Glass paginiert automatisch Seitenelemente, auf denen text angezeigt wird. Wenn Glass html automatisch paginieren soll, verwenden Sie das article-Tag und setzen Sie die Klasseneigenschaft auf auto-paginate wie im folgenden Beispiel:

<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>

Wenn du die Seiten manuell paginieren möchtest, verwende das article-Tag für den Inhalt, den du auf jeder Karte anzeigen möchtest. Glass zeigt den Inhalt jedes article-Tags in einer separaten untergeordneten Zeitleiste an. Sie können beispielsweise ein mit Seitenzahlen versehenes Zeitachsenelement mit folgendem HTML-Code erstellen:

<article>
 <section>
   <p>First page</p>
 </section>
</article>

<article>
 <section>
   <p>Second page</p>
 </section>
</article>

<article>
 <section>
   <p>Third page</p>
 </section>
</article>

Standardmäßig wird die erste Karte des paginierten Zeitachsenelements als Titelkarte angezeigt. Sie wird wieder eingeblendet, wenn der Nutzer den Menüpunkt Weitere Informationen auswählt. Damit die erste Karte nach dem Tippen auf Weitere Informationen nicht wieder angezeigt wird, können Sie die CSS-Klasse cover-only für das erste <article>-Tag angeben:

<article class="cover-only">
...

Die cover-only-Klasse unterstützt auch automatisch paginierte Zeitachsenelemente:

<article class="auto-paginate cover-only">
...

Bündelung

Mithilfe von Gruppierungen können Sie zusammengehörige, aber unterschiedliche Elemente gruppieren, z. B. für einzelne Nachrichten in einer E-Mail-Konversation. Sets haben eine Haupttitelkarte, auf die ein Nutzer tippt, um eine Zwischenzeitleiste mit den anderen Karten im Set aufzurufen. Sets unterscheiden sich von normalen Zeitachsenkarten durch eine umfaltbare Ecke oben rechts auf der Titelkarte des Sets.

Wenn Sie Zeitachsenelemente bündeln möchten, erstellen Sie sie mit demselben Wert für bundleId. Das zuletzt hinzugefügte Element ist die Titelkarte des Sets.

Die folgenden Bilder zeigen eine Set-Cover-Karte mit einer Eckfaltung oben rechts und zwei Karten im Set darunter.

Zeitachsenelemente werden gelesen

Der Dienst kann auf alle von ihm erstellten und auf alle Zeitachsenelemente zugreifen, die für ihn freigegeben wurden. So auflisten Sie die Zeitachsenelemente, die für Ihren Dienst sichtbar sind.

HTTP-Rohdaten

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()

Mit anderen REST-Vorgängen können Sie Zeitachsenelemente abrufen, aktualisieren und löschen.

Auf Anhänge zugreifen

Der Zugriff auf Anhänge eines Zeitachsenelements ist über die Arrayeigenschaft attachments möglich. Sie können die Binärdaten eines Anhangs dann über das Attribut contentUrl des Anhangs oder über den Endpunkt für Anhänge abrufen.

HTTP-Rohdaten

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();

Menüpunkte werden erstellt

Über Menüelemente können Nutzer Aktionen anfordern, die sich auf die Zeitachsenkarte beziehen. Es gibt zwei Arten von Menüelementen: integrierte Menüelemente und benutzerdefinierte Menüelemente.

Integrierte Menüpunkte bieten Zugriff auf spezielle Funktionen von Glass. Beispielsweise können Sie eine Zeitachsenkarte laut vorlesen, zu einem Ort navigieren, ein Bild teilen oder auf eine Nachricht antworten:

Mithilfe von benutzerdefinierten Menüpunkten kann Ihre Anwendung ein Verhalten anzeigen, das für Ihre Glassware spezifisch ist. Sie können auch ein Symbol für Menüoptionen bereitstellen, das zu Ihrem Branding passt.

Integrierte Menüelemente hinzufügen

Sie können Ihren Zeitachsenelementen integrierte Menüelemente hinzufügen, indem Sie die menuItems array beim Einfügen ausfüllen. Wenn Sie einen integrierten Menüpunkt verwenden möchten, müssen Sie nur den action jedes menuItem ausfüllen.

HTTP-Rohdaten

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"
    }
  ]
}

Benutzerdefinierte Menüelemente definieren

Wenn integrierte Menüelemente für Sie nicht geeignet sind, können Sie benutzerdefinierte Menüelemente mit eigenen Aktionen erstellen. Gehen Sie dazu beim Einfügen oder Aktualisieren eines Zeitachsenelements so vor:

  • CUSTOM für menuItem.action angeben.
  • Geben Sie einen menuItem.id an. Wenn Nutzer auf den benutzerdefinierten Menüpunkt tippen, erhält Ihre Glassware eine Benachrichtigung mit menuItem.id. So können Sie die Quelle der Benachrichtigung bestimmen.
  • Geben Sie menuItem.values an, um eine iconUrl und eine displayName hinzuzufügen, die in Glass angezeigt werden. Bewegen Sie den Mauszeiger auf ein PNG-Bild im Format 50 × 50, das in weiß mit transparentem Hintergrund für iconUrl ist.
  • Geben Sie einen displayTime an. Wenn Sie keinen displayTime angeben, rückt das Zeitachsenelement in den Vordergrund der Zeitachse, sobald ein Nutzer auf den benutzerdefinierten Menüpunkt tippt.

HTTP-Rohdaten

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"
      }]
    }
  ]
}

Nutzern erlauben, Ihre Zeitachse anzupinnen

Sie können einen Menüpunkt erstellen, mit dem Ihre Nutzer die Zeitachsenkarte anpinnen können. Dadurch wird die Zeitachse dauerhaft links neben der Hauptuhrkarte angezeigt. Nutzer können die Karte auch über denselben Menüpunkt loslösen.

Das Anpinnen-Menüelement ist ein integrierter Menüpunkt. Sie müssen also nur das TOGGLE_PINNED-action-Element für eine menuItem angeben.

HTTP-Rohdaten

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"
    }
  ...
 ]
}

Abos

Mit der Mirror API können Sie Benachrichtigungen abonnieren, die gesendet werden, wenn der Nutzer bestimmte Aktionen für ein Zeitachsenelement ausführt oder der Nutzerstandort aktualisiert wurde. Wenn Sie eine Benachrichtigung abonnieren, geben Sie eine Callback-URL an, die die Benachrichtigung verarbeitet.

Benachrichtigungen erhalten

Eine Benachrichtigung von der Mirror API wird als POST-Anfrage mit dem Text der JSON-Anfrage an den abonnierten Endpunkt gesendet.

HTTP-Rohdaten

{
  "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)

Wenn kein Fehler aufgetreten ist, muss Ihr Dienst mit dem HTTP-Statuscode 200 OK an die API antworten. Wenn der Dienst einen Fehlercode zurückgibt, versucht die Mirror API möglicherweise, die Benachrichtigung noch einmal an den Dienst zu senden.

Benachrichtigungstypen

Die Mirror API sendet für verschiedene Ereignisse eine andere Benachrichtigungsnutzlast.

Antworten

Der Nutzer hat über den integrierten REPLY-Menüpunkt auf deine Zeitachse geantwortet:

{
  "collection": "timeline",
  "itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
  "operation": "INSERT",
  "userToken": "harold_penguin",
  "verifyToken": "random_hash_to_verify_referer",
  "userActions": [
    {
      "type": "REPLY"
    }
  ]
}

Das Attribut itemId ist auf die ID des Elements festgelegt, das Folgendes enthält:

  • Das Attribut inReplyTo, das auf den ID des Zeitachsenelements festgelegt ist, auf das es eine Antwort ist.
  • Das Attribut text, das auf die Texttranskription festgelegt ist.
  • Das recipients-Attribut, das auf creator des Zeitachsenelements festgelegt ist, auf das es eine Antwort ist, sofern vorhanden.

Beispiel:

{
  "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"
      ]
    }
  ]
}

Löschen

Der Nutzer hat ein Zeitachsenelement gelöscht:

{
  "collection": "timeline",
  "itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
  "operation": "DELETE",
  "userToken": "harold_penguin",
  "verifyToken": "random_hash_to_verify_referer",
  "userActions": [
    {
      "type": "DELETE"
    }
  ]
}

Das Attribut itemId ist auf die ID des gelöschten Elements festgelegt. Das Element enthält außer seiner ID und dem Attribut isDeleted keine Metadaten mehr.

Benutzerdefinierter Menüpunkt ausgewählt

Der Nutzer hat einen von Ihrem Dienst festgelegten benutzerdefinierten Menüpunkt ausgewählt:

{
  "collection": "timeline",
  "itemId": "3hidvm0xez6r8_dacdb3103b8b604_h8rpllg",
  "operation": "UPDATE",
  "userToken": "harold_penguin",
  "userActions": [
    {
      "type": "CUSTOM",
      "payload": "PING"
    }
  ]
}

Das Attribut itemId ist auf die ID des Menüpunkts festgelegt, den der Nutzer ausgewählt hat.

Das Array userActions enthält die Liste der benutzerdefinierten Aktionen, die der Nutzer für dieses Element ausgeführt hat. Ihr Dienst sollte diese Aktionen entsprechend verarbeiten.

Standortaktualisierung

Für den aktuellen Nutzer ist ein neuer Standort verfügbar:

{
  "collection": "locations",
  "itemId": "latest",
  "operation": "UPDATE",
  "userToken": "harold_penguin",
  "verifyToken": "random_hash_to_verify_referer"
}

Wenn Glassware ein Standortupdate erhält, senden Sie eine Anfrage an den Endpunkt glass.locations.get, um den letzten bekannten Standort abzurufen. Ihre Glassware erhält alle zehn Minuten Standortupdates.

Sprachbefehl

Der Nutzer hat einen Sprachbefehl aktiviert, zum Beispiel: "Ok Glass, Notiz schreiben, Katzenstream, Chipotle hat morgen Geburtstag". Die folgende Benachrichtigung wird an Ihre Glassware gesendet:

{
  "collection": "timeline",
  "operation": "INSERT",
  "userToken": "chipotle's_owner",
  "verifyToken": "mew mew mew",
  "itemId": "<ITEM_ID>",
  "userActions": [
    {“type”: "LAUNCH"}
  ]
}

Diese Benachrichtigung unterscheidet sich von anderen Benachrichtigungen durch den Wert LAUNCH im Attribut userActions.

Anschließend können Sie den Wert in itemId verwenden, um das Zeitachsenelement abzurufen:

{
  "id": "<ITEM_ID>",
  "text": "Chipotle's birthday is tomorrow",
  "recipients": [
    {"id": "CAT_STREAM"}
  ]
}

Das Attribut recipients enthält die id des Kontakts, der den verwendeten Sprachbefehl repräsentiert.