يمكنك إدراج البطاقات الثابتة وتحديثها وقراءتها وحذفها باستخدام واجهات برمجة تطبيقات REST البسيطة. بالإضافة إلى ذلك، يمكنك إرفاق عناصر ببطاقة ثابتة، مثل موقع أو وسائط.
آلية عملها
تتواجد البطاقات الثابتة على يمين الساعة الزجاجية بشكل افتراضي وتعرض المعلومات ذات الصلة بالمستخدم في وقت التسليم. مع ذلك، لا تتطلّب هذه البطاقات اهتمامًا فوريًا، مثل البطاقات المباشرة، ويمكن للمستخدمين اختيار قراءة البطاقة أو التفاعل معها في وقت فراغهم.
عندما تُدرج 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" }
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()
عند نجاح الإجراء، ستتلقّى رمز الاستجابة 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--
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()
عنصر مخطط زمني مع صورة مرفقة يبدو على النحو التالي على Glass:
جارٍ إرفاق الفيديو
في حال إرفاق ملفات فيديو بعناصر المخطط الزمني، ننصحك ببث الفيديو بدلاً من تحميل حمولة البيانات بالكامل دفعة واحدة. تتيح واجهة برمجة التطبيقات Google Mirror API البث المباشر من خلال بث HTTP المباشر والتنزيل التدريجي وبروتوكول البث في الوقت الفعلي (RTSP). غالبًا ما يتم حظر بروتوكول RTSP بواسطة جدران الحماية، لذا استخدِم الخيارات الأخرى متى أمكن ذلك.
لبث فيديو، استخدِم عنصر القائمة PLAY_VIDEO
المضمّن
وحدِّد عنوان URL للفيديو ليكون في عنصر القائمة
payload
. راجع إضافة عناصر القائمة المضمنة وتنسيقات الوسائط المتوافقة للحصول على مزيد من المعلومات.
التقسيم على صفحات
يمكنك تقسيم عناصر المخطط الزمني إلى صفحات لا تناسب بطاقة مخطط زمني واحد،
ولكن يجب ربطها بالبطاقة نفسها. تشترك جميع العناصر المقسّمة على صفحات في timeline.id
نفسه، وبالتالي تكون المجموعة نفسها من عناصر القائمة. عندما ينقر المستخدم على عنصر مخطط زمني مقسّم على صفحات، يظهر عنصر في القائمة
قراءة المزيد.
يقسّم Glass تلقائيًا عناصر المخطط الزمني التي تعرض text
. لتقسيم html
تلقائيًا إلى صفحات في Glass، استخدِم علامة 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}
Java
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}
Java
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>"
}
]
}
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)
في حال عدم حدوث أي خطأ، يجب أن تستجيب الخدمة لواجهة برمجة التطبيقات باستخدام رمز حالة 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، عيد ميلاد تشيبوتل غدًا". تم إرسال الإشعار التالي إلى 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
لجهة الاتصال التي تمثّل الطلب الصوتي المُستخدَم.