إنشاء تطبيق ويب للوصول إلى الأجهزة

1. مقدمة

يوفّر برنامج "الوصول إلى الأجهزة" واجهة برمجة التطبيقات Smart Device Management API، وهي واجهة برمجة تطبيقات REST تتيح للمطوّرين التحكّم في أجهزة Google Nest من خلال تطبيقاتهم. على المستخدمين الموافقة على منح إذن وصول الجهات الخارجية إلى أجهزة Nest.

52f77aa38cda13a6.png

هناك ثلاث خطوات رئيسية لدمج تطبيق "الوصول إلى الأجهزة" بنجاح:

  1. إنشاء مشروع: يمكنك إنشاء مشروع في Google Cloud Platform والاشتراك كمطوِّر في Device Access Console.
  2. ربط الحسابات: يمكنك جذب المستخدمين من خلال عملية ربط الحسابات واسترداد رمز الدخول. استبدِل الرمز برمز الدخول.
  3. التحكُّم في الجهاز: يمكنك إرسال طلبات من خلال واجهة برمجة التطبيقات لإدارة الأجهزة الذكية للتحكّم في الأجهزة من خلال إرسال الأوامر باستخدام رمز الدخول.

في هذا الدرس التطبيقي حول الترميز، سنتناول بالتفصيل آلية عمل تطبيق "الوصول إلى الأجهزة" من خلال إنشاء تطبيق ويب لمعالجة المصادقة وإجراء طلبات البيانات من واجهة برمجة التطبيقات لإدارة الأجهزة الذكية. وسنستكشف أيضًا نشر خادم وكيل بسيط باستخدام Node.js و Express لتوجيه طلبات الوصول إلى الجهاز.

قبل البدء، قد يكون من المفيد استكشاف تكنولوجيات الويب الشائعة التي سنستخدمها في هذا الدرس التطبيقي حول الترميز، مثل المصادقة باستخدام OAuth 2.0 أو إنشاء تطبيق ويب باستخدام Node.js، مع أنّها ليست متطلبات أساسية.

المتطلبات

  • Node.js 8 أو أحدث
  • حساب Google مع جهاز Nest Thermostat مرتبط

ما ستتعلمه

  • إعداد مشروع Firebase لاستضافة صفحات الويب الثابتة والوظائف السحابية
  • إصدار طلبات الوصول إلى الجهاز من خلال تطبيق ويب مستنِد إلى المتصفِّح
  • إنشاء خادم وكيل باستخدام Node.js و Express لتوجيه طلباتك

2. إنشاء مشروع

على المطوّرين إنشاء مشروع Google Cloud Platform (GCP) لإعداد دمج Device Access. سيتم استخدام رقم تعريف العميل وسر العميل اللذين يتم إنشاؤهما ضمن مشروع Google Cloud Platform كجزء من مسار OAuth بين تطبيق المطوّر وGoogle Cloud. على المطوّرين أيضًا الانتقال إلى Device Access Console لإنشاء مشروع للوصول إلى Smart Device Management API.

Google Cloud Platform

انتقِل إلى Google Cloud Platform. انقر على "إنشاء مشروع جديد" وأدخِل اسم المشروع. سيتم أيضًا عرض رقم تعريف المشروع [GCP-Project-Id] لخدمة Google Cloud. يُرجى تسجيله لأنّنا سنستخدمه أثناء إعداد Firebase. (سنشير إلى رقم التعريف هذا باسم [GCP-Project-Id] في هذا الدرس التطبيقي حول الترميز).

585e926b21994ac9.png

الخطوة الأولى هي تفعيل مكتبة واجهة برمجة التطبيقات (API) اللازمة في مشروعنا. انتقِل إلى واجهات برمجة التطبيقات الخدمات > المكتبة وابحث عن Smart Device Management API. عليك تفعيل واجهة برمجة التطبيقات هذه من أجل تفويض مشروعك لتقديم طلبات إلى بيانات طلبات البيانات من واجهة برمجة التطبيقات Device Access API.

14e7eabc422c7fda.png

قبل الانتقال إلى إنشاء بيانات اعتماد OAuth، نحتاج إلى ضبط شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth لمشروعنا. انتقِل إلى واجهات برمجة التطبيقات الخدمات > شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth بالنسبة إلى نوع المستخدم، اختَر خارجي. أدخِل اسمًا وعنوان بريد إلكتروني للدعم الخاص بتطبيقك، بالإضافة إلى معلومات الاتصال بالمطوِّر لإكمال الشاشة الأولى. عندما يُطلب منك المستخدمون التجريبيون، احرص في هذه الخطوة على تقديم عنوان البريد الإلكتروني مع الأجهزة المرتبطة.

بعد ضبط شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth، انتقِل إلى واجهات برمجة التطبيقات الخدمات > بيانات الاعتماد: انقر على +إنشاء بيانات اعتماد واختَر معرِّف عميل OAuth. بالنسبة إلى نوع التطبيق، اختَر تطبيق الويب.

5de534212d44fce7.png

أدخِل اسمًا لعميلك وانقر على إنشاء. سنضيف لاحقًا مصدر JavaScript مسموحًا به ومعرّف الموارد المنتظم (URI) المعتمَد لإعادة التوجيه. سيؤدي إكمال هذه العملية إلى ظهور [Client-Id] و[Client-Secret] المرتبط بعميل OAuth 2.0 هذا.

e6a670da18952f08.png

وحدة التحكّم في الوصول إلى الجهاز

انتقِل إلى وحدة التحكّم في الوصول إلى الجهاز. إذا لم يسبق لك استخدام "وحدة التحكّم في الوصول إلى الأجهزة"، ستتم الترحيب بك باتفاقية بنود الخدمة مع رسوم تسجيل بقيمة 5 دولار أمريكي.

أنشِئ مشروعًا جديدًا واعطه اسم مشروع. في النافذة التالية، أدخِل [Client-Id] الذي تلقّيته من Google Cloud Platform في الخطوة السابقة.

f8a3f27354bc2625.png

سينقلك تمكين الأحداث وإنهاء خطوات إنشاء المشروع إلى الصفحة الرئيسية لمشروعك. سيتم إدراج [Project-Id] تحت الاسم الذي منحته لمشروعك.

db7ba33d8b707148.png

يُرجى الإشارة إلى [Project-Id] لأنّه سنستخدمه عند إرسال الطلبات إلى Smart Device Management API.

3- إعداد Firebase

يوفّر Firebase للمطوّرين طريقة سريعة وسهلة لنشر تطبيقات الويب. سنطوّر تطبيق ويب من جهة العميل لدمج تطبيق "الوصول إلى الأجهزة" باستخدام Firebase.

إنشاء مشروع Firebase

انتقِل إلى وحدة تحكُّم Firebase. انقر على إضافة مشروع، ثم اختَر المشروع الذي أنشأته في خطوة إنشاء مشروع. سيؤدي هذا الإجراء إلى إنشاء مشروع Firebase ليتم ربطه بمشروع Google Cloud Platform [GCP-Project-Id].

بعد إنشاء مشروع Firebase بنجاح، من المفترض أن تظهر لك الشاشة التالية:

dbb02bbacac093f5.png

تثبيت أدوات Firebase

يوفّر Firebase مجموعة من أدوات واجهة سطر الأوامر لإنشاء تطبيقك ونشره. لتثبيت هذه الأدوات، افتح نافذة طرفية جديدة وشغِّل الأمر التالي. سيؤدي هذا الإجراء إلى تثبيت أدوات Firebase على مستوى العالم.

$ npm i -g firebase-tools

للتأكّد من تثبيت أدوات Firebase بشكل صحيح، تحقَّق من معلومات الإصدار.

$ firebase --version

يمكنك تسجيل الدخول إلى أدوات واجهة سطر الأوامر في Firebase باستخدام حسابك على Google باستخدام أمر تسجيل الدخول.

$ firebase login

إعداد مشروع الاستضافة

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

$ firebase init hosting

سيطرح عليك Firebase مجموعة من الأسئلة للبدء في مشروع استضافة:

  1. يُرجى تحديد خيار: استخدام مشروع حالي
  2. اختيار مشروع تلقائي في Firebase لهذا الدليل — اختيار***[GCP-Project-Id]***
  3. ما الذي تريد استخدامه كدليل عام؟ — علنية
  4. هل تريد ضبطه كتطبيق من صفحة واحدة؟ — نعم
  5. هل تريد إعداد إصدارات ونشر تلقائية باستخدام GitHub؟ — لا

بعد إعداد مشروعك، يمكنك نشره على firebase باستخدام الأمر التالي:

$ firebase deploy

سيفحص Firebase مشروعك وينشر الملفات اللازمة في الاستضافة على السحابة الإلكترونية.

fe15cf75e985e9a1.png

عند فتح عنوان URL للاستضافة في أحد المتصفحات، يُفترض أن تظهر لك الصفحة التي نشرتها للتو:

e40871238c22ebe2.png

بعد أن تعرفت على أساسيات نشر صفحة ويب باستخدام Firebase، فلنبدأ في نشر نموذج درس تطبيقي حول الترميز.

4. عيّنة من الدروس التطبيقية حول الترميز

يمكنك استنساخ مستودع درس تطبيقي حول الترميز المستضاف على GitHub، باستخدام الأمر أدناه:

$ git clone https://github.com/google/device-access-codelab-web-app.git

نقدم في هذا المستودع عينات في مجلدين منفصلين. يحتوي مجلد "codelab-start" على الملفات اللازمة للبدء من المرحلة الحالية في هذا الدرس التطبيقي حول الترميز. يحتوي مجلد "codelab-done" على إصدار كامل من هذا الدرس التطبيقي، بالإضافة إلى برنامج يعمل بكامل طاقته وخادمNode.js.

سنستخدم الملفات من مجلد "codelab-start" في هذا الدرس التطبيقي حول الترميز، ولكن إذا واجهت صعوبة في أي وقت، يمكنك الرجوع إلى الإصدار الذي تم إنجازه من خلال الدرس التطبيقي حول الترميز.

نماذج ملفات درس تطبيقي حول الترميز

في ما يلي بنية ملف مجلد Codelab-start:

public
├───index.html
├───scripts.js
├───style.css
firebase.json

يحتوي المجلد العام على صفحات ثابتة من تطبيقنا. إنّ firebase.json مسؤول عن توجيه طلبات الويب إلى تطبيقنا. في الإصدار codelab-done، سيظهر لك أيضًا الدليل functions الذي يحتوي على منطق الخادم الوكيل (express) الذي سيتم نشره على دوال Google Cloud.

نشر نموذج درس تطبيقي حول الترميز

انسخ الملفات من codelab-start إلى دليل مشروعك.

$ firebase deploy

بعد انتهاء Firebase من عملية النشر، من المفترض أن تتمكّن من الاطّلاع على تطبيق Codelab:

e84c1049eb4cca92.png

يتطلب بدء مسار المصادقة بيانات اعتماد الشريك، والتي سنتناولها في القسم التالي.

5- التعامل مع بروتوكول OAuth

OAuth هو معيار الويب لتفويض الوصول، ويشيع استخدامه لمنح المستخدمين لتطبيقات الجهات الخارجية حق الدخول إلى معلومات حساباتهم بدون مشاركة كلمات المرور. نستخدم OAuth 2.0 لتمكين المطوّرين من الوصول إلى أجهزة المستخدمين من خلال الوصول إلى الأجهزة.

7ee31f5d9c37f699.png

تحديد عنوان URI لإعادة التوجيه

تتضمن الخطوة الأولى من مسار OAuth تمرير مجموعة من المَعلَمات إلى نقطة نهاية Google OAuth 2.0. وبعد الحصول على موافقة المستخدم، ستصدر خوادم Google OAuth طلبًا برمز تفويض إلى معرّف الموارد المنتظم (URI) الخاص بإعادة التوجيه.

تعديل ثابت SERVER_URI (السطر 19) باستخدام عنوان URL للاستضافة الخاص بك في scripts.js:

const SERVER_URI = "https://[GCP-Project-Id].web.app";

ستؤدي إعادة نشر التطبيق بعد تطبيق هذا التغيير إلى تعديل معرّف الموارد المنتظم (URI) الخاص بإعادة التوجيه المُستخدَم لمشروعك.

$ firebase deploy

تفعيل عنوان URI لإعادة التوجيه

بمجرد تحديث معرف الموارد المنتظم (URI) لإعادة التوجيه في ملف النصوص البرمجية، يجب عليك أيضًا إضافته إلى قائمة معرفات الموارد المنتظمة (URI) المسموح بها لإعادة التوجيه لمعرف العميل الذي قمت بإنشائه لمشروعك. انتقِل إلى صفحة بيانات الاعتماد في Google Cloud Platform، حيث ستسرد جميع بيانات الاعتماد التي تم إنشاؤها لمشروعك:

1a07b624b5e548da.png

ضمن قائمة معرّفات عميل OAuth 2.0، اختَر معرِّف العميل الذي أنشأته في خطوة إنشاء المشروع. أضِف معرِّف الموارد المنتظم (URI) الخاص بإعادة التوجيه لتطبيقك إلى قائمة معرّفات الموارد المنتظمة (URI) المعتمَدة لإعادة التوجيه لمشروعك.

6d65b298e1f005e2.png

يُرجى محاولة تسجيل الدخول.

انتقِل إلى عنوان URL للاستضافة الذي أعددته باستخدام Firebase، وأدخِل بيانات اعتماد الشريك وانقر على زر تسجيل الدخول. معرّف العميل وسر العميل هما بيانات الاعتماد التي حصلت عليها من Google Cloud Platform، ورقم تعريف المشروع من وحدة تحكم الوصول إلى الجهاز.

78b48906a2dd7c05.png

سينقل الزر تسجيل الدخول المستخدمين خلال مسار OAuth لمؤسستك، بدءًا بشاشة تسجيل الدخول إلى حساباتهم على Google. بعد تسجيل الدخول، سيُطلب من المستخدمين منح أذونات لمشروعك للوصول إلى أجهزة Nest.

e9b7887c4ca420.png

بما أنّ هذا التطبيق وهمي، ستصدر Google تحذيرًا قبل إصدار عملية إعادة التوجيه.

b227d510cb1df073.png

انقر على "الإعدادات المتقدّمة"، ثم اختَر "الانتقال إلى web.app (غير آمن)" لإكمال عملية إعادة التوجيه إلى تطبيقك.

673a4fd217e24dad.png

سيؤدي ذلك إلى توفير رمز OAuth كجزء من طلب GET الوارد، والذي سيستبدله التطبيق بعد ذلك برمز الدخول ورمز التحديث.

6- التحكّم في الجهاز

يستخدم نموذج تطبيق "الوصول إلى الأجهزة" طلبات البيانات من واجهة برمجة التطبيقات Smart Device Management REST API للتحكّم في أجهزة Google Nest. تتضمن هذه الاتصالات تمرير رمز الدخول في رأس طلب GET أو POST، إلى جانب الحمولة المطلوبة لأوامر معينة.

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

function deviceAccessRequest(method, call, localpath, payload = null) {...}
  • الطريقة: نوع طلب HTTP (GET أو POST)
  • طلب — سلسلة تمثل طلب البيانات من واجهة برمجة التطبيقات، وتُستخدم لتوجيه الردود (listDevices، وthermostatMode، وtemperatureSetpoint)
  • Localpath: نقطة النهاية التي يتم تقديم الطلب إليها، وتحتوي على رقم تعريف المشروع ورقم تعريف الجهاز (الملحق بعد https://smartdevicemanagement.googleapis.com/v1).
  • الحمولة (*) - البيانات الإضافية المطلوبة لاستدعاء واجهة برمجة التطبيقات (على سبيل المثال، القيمة الرقمية التي تمثل درجة الحرارة لنقطة تعيين)

سننشئ نماذج عناصر تحكّم في واجهة المستخدم (إدراج الأجهزة، وتعيين الوضع، وضبط درجة الحرارة) للتحكم في جهاز Nest Thermostat:

86f8a193aa397421.png

ستستدعي عناصر التحكّم هذه في واجهة المستخدم الدوال المقابلة (listDevices() وpostThermostatMode() وpostTemperatureSetpoint()) من scripts.js. ويتم تركها فارغة لك لتنفّذها! الهدف هو اختيار الطريقة/المسار الصحيح وتمرير الحمولة إلى دالة deviceAccessRequest(...).

إدراج الأجهزة

أبسط مكالمة للوصول إلى الجهاز هي listDevices. وهي تستخدم طلب GET ولا تتطلب أي حمولة. يجب تنظيم نقطة النهاية باستخدام projectId. أكمِل دالة listDevices() على النحو التالي:

function listDevices() {
  var endpoint = "/enterprises/" + projectId + "/devices";
  deviceAccessRequest('GET', 'listDevices', endpoint);
}

احفظ التغييرات وانشر مشروع Firebase مرة أخرى باستخدام الأمر التالي:

$ firebase deploy

بعد نشر الإصدار الجديد من التطبيق، جرِّب إعادة تحميل الصفحة والنقر على إدراج الأجهزة. من المفترض أن يؤدي ذلك إلى تعبئة القائمة ضمن "التحكّم في الجهاز"، والتي من المفترض أن يظهر لك معرّف الترموستات:

b64a198673ed289f.png

سيؤدي اختيار الأجهزة من القائمة إلى تعديل الحقل deviceId في ملف scripts.js. بالنسبة إلى عنصرَي التحكّم التاليين، سنحتاج إلى تحديد deviceId للجهاز المحدّد الذي نريد التحكّم فيه.

التحكّم في الترموستات

هناك سمتان للتحكّم الأساسي في جهاز Nest Thermostat في واجهة برمجة التطبيقات Smart Device Management API. ThermostatMode وTemperatureSetpoint. يضبط ThermostatMode وضع Nest Thermostat على أحد الأوضاع الأربعة المختلفة المحتملة: {إيقاف، تدفئة، تبريد، تبريد ضوئي}. بعد ذلك، نحتاج إلى توفير الوضع المحدّد كجزء من الحمولة.

استبدل دالة postThermostatMode() في scripts.js بما يلي:

function postThermostatMode() {
  var endpoint = "/enterprises/" + projectId + "/devices/" + deviceId + ":executeCommand";
  var tempMode = id("tempMode").value;
  var payload = {
    "command": "sdm.devices.commands.ThermostatMode.SetMode",
    "params": {
      "mode": tempMode
    }
  };
  deviceAccessRequest('POST', 'thermostatMode', endpoint, payload);
}

تعالج الدالة التالية، postTemperatureSetpoint()، ضبط درجة الحرارة (بالدرجة المئوية) في جهاز Nest Thermostat. هناك مَعلمتان يمكن ضبطهما في الحمولة، heatCelsius وcoolCelsius، استنادًا إلى وضع الترموستات المحدّد.

function postTemperatureSetpoint() {
  var endpoint = "/enterprises/" + projectId + "/devices/" + deviceId + ":executeCommand";
  var heatCelsius = parseFloat(id("heatCelsius").value);
  var coolCelsius = parseFloat(id("coolCelsius").value);

  var payload = {
    "command": "",
    "params": {}
  };
  
  if ("HEAT" === id("tempMode").value) {
    payload.command = "sdm.devices.commands.ThermostatTemperatureSetpoint.SetHeat";
    payload.params["heatCelsius"] = heatCelsius;
  }
  else if ("COOL" === id("tempMode").value) {
    payload.command = "sdm.devices.commands.ThermostatTemperatureSetpoint.SetCool";
    payload.params["coolCelsius"] = coolCelsius;
  }
  else if ("HEATCOOL" === id("tempMode").value) {
    payload.command = "sdm.devices.commands.ThermostatTemperatureSetpoint.SetRange";
    payload.params["heatCelsius"] = heatCelsius;
    payload.params["coolCelsius"] = coolCelsius;
  } else {
    console.log("Off and Eco mode don't allow this function");
    return;
  }
  deviceAccessRequest('POST', 'temperatureSetpoint', endpoint, payload);
}

7. خادم Node.js (اختياري)

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

بالنسبة إلى هذا الخادم الوكيل، سنستخدم وظائف السحابة الإلكترونية في Firebase، Node.js و Express.

إعداد وظائف السحابة الإلكترونية

افتح نافذة طرفية جديدة وانتقل إلى دليل المشروع ونفِّذ ما يلي:

$ firebase init functions

سيطرح عليك Firebase مجموعة من الأسئلة لإعداد وظائف السحابة الإلكترونية:

  1. ما هي اللغة التي تريد استخدامها لكتابة دوال Cloud؟ — JavaScript
  2. هل تريد استخدام ESLint لاكتشاف الأخطاء المحتملة وتعزيز أسلوبك في اللعب؟ — لا
  3. هل تريد الآن تثبيت الاعتماديات باستخدام npm؟ — نعم

سيؤدي هذا الإجراء إلى إعداد مجلد "functions" في مشروعك، بالإضافة إلى تثبيت الملحقات اللازمة. سيظهر لك أن مجلّد مشروعك يحتوي على دليل وظائف، مع ملف index.js لتحديد دوال السحابة الإلكترونية، package.json لتحديد الإعدادات ودليل node_modules يحتوي على التبعيات.

سنستخدم مكتبتَين npm لإنشاء الوظيفة من جهة الخادم، وهما Express وxmlhttprequest. ستحتاج إلى إضافة الإدخالات التالية إلى قائمة التبعيات في ملف package.json:

"xmlhttprequest": "^1.8.0",
"express": "^4.17.0"

بعد ذلك، يجب أن يؤدي تشغيل npm install من دليل الدوال إلى تثبيت تبعيات لمشروعك:

$ npm install

إذا واجه npm مشكلة في تنزيل الحِزم، يمكنك محاولة حفظ xmlhttprequest وexpress بشكل صريح باستخدام الأمر التالي:

$ npm install express xmlhttprequest --save

الترقية إلى خطة Blaze

عند استخدام الأمر firebase deploy، عليك الترقية إلى خطة Blaze، ما يتطلّب إضافة طريقة دفع إلى حسابك. انتقِل إلى نظرة عامة على المشروع >. الاستخدام والفوترة وتأكَّد من اختيار خطة Blaze لمشروعك

c6a5e5a21397bef6.png

Build Express Server

يتّبع خادم Express إطار عمل بسيطًا للردّ على طلبات GET وPOST الواردة. لقد صممنا خادمًا يصغي إلى طلبات POST، وينقلها إلى عنوان URL مقصود محدد في الحمولة، ويستجيب بالاستجابة التي تتلقاها من عملية النقل.

عدِّل ملف index.js في دليل الدوال ليظهر كما يلي:

const XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const functions = require('firebase-functions');
const express = require('express');
const http = require('http');

const app = express();
app.use(express.json());


//***** Device Access - Proxy Server *****//

// Serving Get Requests (Not used) 
app.get('*', (request, response) => {
  response.status(200).send("Hello World!");
});
// Serving Post Requests
app.post('*', (request, response) => {
  
  setTimeout(() => {
    // Read the destination address from payload:
    var destination = request.body.address;
    
    // Create a new proxy post request:
    var xhr = new XMLHttpRequest();
    xhr.open('POST', destination);
    
    // Add original headers to proxy request:
    for (var key in request.headers) {
            var value = request.headers[key];
      xhr.setRequestHeader(key, value);
    }
    
    // Add command/parameters to proxy request:
    var newBody = {};
    newBody.command = request.body.command;
    newBody.params = request.body.params;
    
    // Respond to original request with the response coming
    // back from proxy request (to Device Access Endpoint)
    xhr.onload = function () {
      response.status(200).send(xhr.responseText);
    };
    
    // Send the proxy request!
    xhr.send(JSON.stringify(newBody));
  }, 1000);
});

// Export our app to firebase functions:
exports.app = functions.https.onRequest(app);

لنتمكّن من توجيه الطلبات إلى خادمنا، نحتاج إلى تعديل عمليات إعادة الكتابة من firebase.json على النحو التالي:

{
  "hosting": {
    "public": "public",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [{
        "source": "/proxy**",
        "function": "app"
      },{
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

سيؤدي هذا الإجراء إلى توجيه عناوين URL التي تبدأ بـ /proxy إلى خادم Express، وستستمر بقية عناوين URL في الانتقال إلى index.html.

طلبات البيانات من واجهة برمجة التطبيقات الوكيلة

والآن بعد أن أصبح الخادم جاهزًا، لنحدد معرف موارد منتظم (URI) لخادم وكيل في scripts.js لكي يرسل المتصفّح الطلبات إلى هذا العنوان:

const PROXY_URI = SERVER_URI + "/proxy";

بعد ذلك، أضِف الدالة proxyRequest وهي scripts.js، التي لها توقيع الدالة deviceAccessRequest(...) نفسه، وذلك لطلبات الوصول غير المباشر إلى الجهاز.

function proxyRequest(method, call, localpath, payload = null) {
    var xhr = new XMLHttpRequest();
    
    // We are doing our post request to our proxy server:
    xhr.open(method, PROXY_URI);
    xhr.setRequestHeader('Authorization', 'Bearer ' + accessToken);
    xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
    xhr.onload = function () {
      // Response is passed to deviceAccessResponse function:
      deviceAccessResponse(call, xhr.response);
    };
    
    // We are passing the device access endpoint in address field of the payload:
    payload.address = "https://smartdevicemanagement.googleapis.com/v1" + localpath;
    if ('POST' === method && payload)
        xhr.send(JSON.stringify(payload));
    else
        xhr.send();
}

الخطوة الأخيرة هي استبدال استدعاءات deviceAccessRequest(...) بالدالة proxyRequest(...) في الدالتين postThermostatMode() وpostTemperatureSetpoint() ضمن scripts.js.

شغِّل "firebase deploy" لتحديث التطبيق.

$ firebase deploy

وبذلك، أصبح لديك الآن خادم وكيل Node.js قيد التشغيل يستخدم Express على دوال السحابة.

تقديم أذونات Cloud Function

الخطوة الأخيرة هي مراجعة أذونات الوصول لوظائف السحابة الإلكترونية والتأكّد من أنّ التطبيق من جهة العميل بإمكانه طلبها.

من Google Cloud Platform، انتقِل إلى علامة التبويب "وظائف السحابة الإلكترونية" من القائمة، ثم اختَر وظيفة السحابة الإلكترونية:

461e9bae74227fc1.png

انقر على الأذونات، ثم إضافة عضو. كتابة allUsers في حقل العضو الجديد، واختيار "Cloud Functions" (دوال السحابة) > "مقدِّم خدمة Cloud Functions" سيؤدي النقر على "حفظ" إلى عرض رسالة تحذير:

3adb01644217578c.png

سيؤدي تحديد "السماح بالوصول العام" إلى جعل التطبيق الجانبي للعميل قادرًا على استخدام وظيفتك السحابية.

تهانينا، لقد أكملت جميع الخطوات. يمكنك الآن الانتقال إلى تطبيق الويب واستخدام عناصر التحكم في الجهاز لتوجيهها عبر الخادم الوكيل.

الخطوات التالية

هل تبحث عن طرق لتوسيع نطاق خبرتك في الوصول إلى الأجهزة؟ يمكنك الاطّلاع على مستندات السمات لمزيد من المعلومات حول التحكّم في أجهزة Nest الأخرى وعملية الحصول على شهادة الاعتماد للتعرّف على الخطوات التي يجب اتّباعها لإطلاق منتجك إلى العالم.

يمكنك تعزيز مهاراتك من خلال نموذج تطبيق الويب "الوصول إلى الجهاز" الذي يمكنك من خلاله الاستفادة من تجربة درس تطبيقي حول الترميز ونشر تطبيق ويب فعال للتحكّم في الكاميرات وأجراس الباب وأجهزة الترموستات من Nest.