البطاقات الثابتة

يمكنك إدراج البطاقات الثابتة وتعديلها وقراءتها وحذفها باستخدام واجهات برمجة تطبيقات REST بسيطة. بالإضافة إلى ذلك، يمكنك إرفاق عناصر ببطاقة ثابتة، مثل موقع جغرافي أو وسائط.

آلية عملها

تظهر البطاقات الثابتة على يسار ساعة Glass تلقائيًا وتعرض معلومات ذات صلة بالمستخدم في وقت التسليم. ومع ذلك، لا تتطلب اهتمامًا فوريًا مثل البطاقات المباشرة ويمكن للمستخدمين اختيار قراءتها أو اتخاذ إجراء بشأن البطاقة في الوقت الذي يناسبهم.

عندما تُدرج Glassware بطاقات ثابتة في المخطط الزمني، قد يصدر Glass صوت إشعار لتنبيه المستخدمين. تنتقل أيضًا جميع البطاقات الثابتة السابقة إلى اليسار وتختفي من المخطط الزمني بعد 7 أيام أو عندما يصبح عدد البطاقات الجديدة 200.

حالات الاستخدام

تُعدّ البطاقات الثابتة رائعة لإرسال إشعارات دورية إلى المستخدمين عند حدوث أحداث مهمة. على سبيل المثال، خدمة إخبارية ترسل أهم الأخبار فور حدوثها. يمكن للبطاقات الثابتة في Mirror API أيضًا بدء البطاقات المباشرة أو التجارب الغامرة من خلال OPEN_URI عنصر القائمة. يسمح لك ذلك بإنشاء تفاعلات مختلطة تستخدم البطاقات الثابتة كإشعارات وبطاقة مباشرة أو تجربة غامرة للحصول على تجربة أكثر تفاعلية.

للحصول على قائمة كاملة بالعمليات المحتمَلة لعناصر المخطط الزمني، يُرجى الاطّلاع على المستندات المرجعية.

إدراج البطاقات الثابتة

لـ إدراج بطاقات ثابتة (عناصر المخطط الزمني)، يمكنك نشر تمثيل JSON لعنصر المخطط الزمني في نقطة نهاية REST.

معظم الحقول في عنصر المخطط الزمني اختيارية. في أبسط أشكاله، لا يحتوي عنصر المخطط الزمني إلا على رسالة نصية قصيرة، كما في هذا المثال:

بروتوكول 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` نفسها، وبالتالي يكون لها مجموعة عناصر القائمة نفسها.timeline.id عندما ينقر المستخدم على عنصر مخطط زمني مرقّم، يظهر عنصر القائمة قراءة المزيد.

يرقّم Glass تلقائيًا عناصر المخطط الزمني التي تعرض text. لجعل Glass يرقّم تلقائيًا html، استخدِم العلامة article مع ضبط سمة الفئة على auto-paginate كما في المثال التالي:

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

تلقائيًا، يتم عرض البطاقة الأولى لعنصر المخطط الزمني المرقّم كبطاقة الغلاف، ويتم عرضها مرة أخرى عندما يختار المستخدم عنصر القائمة قراءة المزيد. لمنع ظهور البطاقة الأولى مرة أخرى بعد النقر على قراءة المزيد، يمكنك تحديد فئة CSS cover-only للعلامة الأولى <article>:

<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 عند إدراجها. لاستخدام عنصر قائمة مُضمّن، ما عليك سوى ملء الـ 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": "Hello world",
  "menuItems": [
    {
      "action": "REPLY"
    }
  ]
}

تحديد عناصر القائمة المخصّصة

إذا لم تنجح عناصر القائمة المُضمّنة، يمكنك إنشاء عناصر قائمة مخصّصة باستخدام الإجراءات الخاصة بك من خلال اتّباع الخطوات التالية عند إدراج عنصر مخطط زمني أو تعديله:

  • حدِّد CUSTOM لـ menuItem.action.
  • حدِّد menuItem.id. عندما ينقر المستخدمون على عنصر القائمة المخصّص، تتلقّى Glassware إشعارًا يتضمّن menuItem.id الذي تم ملؤه. يسمح لك ذلك بتحديد مصدر الإشعار.
  • حدِّد menuItem.values لإضافة iconUrl وdisplayName اللذين يظهران على Glass. أشِر إلى صورة PNG بيضاء بحجم 50 × 50 بكسل بخلفية شفافة لـ iconUrl.
  • حدِّد 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 كطلب POST إلى نقطة النهاية المشترَك فيها التي تحتوي على نص طلب JSON.

بروتوكول 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)

يجب أن تردّ خدمتك على واجهة برمجة التطبيقات باستخدام رمز حالة HTTP 200 OK إذا لم يحدث أي خطأ. إذا ردّت خدمتك برمز خطأ، قد تحاول 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 على معرّف العنصر المحذوف. لم يعُد العنصر يحتوي على بيانات وصفية أخرى غير المعرّف والسمة isDeleted.

تم اختيار عنصر قائمة مخصّص

اختار المستخدم عنصر قائمة مخصّصًا تم ضبطه من قِبل خدمتك:

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

تم ضبط السمة itemId على معرّف عنصر القائمة الذي اختاره المستخدم.

يحتوي صفيف userActions على قائمة بالإجراءات المخصّصة التي اتّخذها المستخدم بشأن هذا العنصر. يجب أن تعالج خدمتك هذه الإجراءات وفقًا لذلك.

إشعار بشأن الموقع الجغرافي

يتوفّر موقع جغرافي جديد للمستخدم الحالي:

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

عندما تتلقّى Glassware إشعارًا بشأن الموقع الجغرافي، أرسِل طلبًا إلى نقطة النهاية glass.locations.get لاسترداد آخر موقع جغرافي معروف. تتلقّى Glassware إشعارات بشأن الموقع الجغرافي كل عشر دقائق.

بطلب صوتي

فعّل المستخدم طلبًا صوتيًا، على سبيل المثال: "Ok Glass، خذ ملاحظة، Cat Stream، عيد ميلاد Chipotle غدًا". يتم إرسال الإشعار التالي إلى 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 لجهة الاتصال التي تمثّل الطلب الصوتي المستخدَم.