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

1- مقدمة

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

52f77aa38cda13a6.png

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

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

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

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

المتطلبات

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

المعلومات التي ستطّلع عليها

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

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

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

Google Cloud Platform

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

585e926b21994ac9.png

الخطوة الأولى هي تفعيل مكتبة واجهة برمجة التطبيقات الضرورية في مشروعنا. انتقِل إلى APIs & Services > Library (المكتبة) وابحث عن 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 مجموعة من أدوات واجهة سطر الأوامر (CLI) لإنشاء تطبيقك ونشره. لتثبيت هذه الأدوات، افتح نافذة طرفية جديدة وشغِّل الأمر التالي. سيؤدي ذلك إلى تثبيت أدوات 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 من النشر، من المفترض أن تتمكّن من الاطّلاع على تطبيق الدرس التطبيقي حول الترميز:

e84c1049eb4cca92.png

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

5. معالجة OAuth

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

7ee31f5d9c37f699.png

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

تتضمن الخطوة الأولى من مسار 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

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

بعد تحديث معرّف الموارد المنتظم (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. التحكّم في الجهاز

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

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

function deviceAccessRequest(method, call, localpath, payload = null) {...}
  • الطريقة - نوع طلب HTTP (GET أو POST)
  • Call — سلسلة تمثّل طلب البيانات من واجهة برمجة التطبيقات وتُستخدم لتوجيه الردود (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 يضبط وضع Thermostat وضع "ترموستات من Nest" على أحد الأوضاع الأربعة المختلفة المحتملة: {Off، التدفئة، التبريد، الحرارة}. بعد ذلك، نحتاج إلى توفير الوضع المحدد كجزء من الحمولة.

استبدل دالة 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. ما اللغة التي تريد استخدامها لكتابة دوال السحابة؟ — 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 والتعبير الصريح باستخدام الأمر التالي:

$ npm install express xmlhttprequest --save

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

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

c6a5e5a21397bef6.png

إنشاء خادم Express

يتّبع خادم Express إطار عمل بسيط للاستجابة إلى طلبات GET وPOST الواردة. لقد أنشأنا خادم servlet يستجيب لطلبات 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 الخاص بنا، وسيستمر انتقال بقية العناوين إلى index.html.

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

بعد أن أصبح الخادم جاهزًا، لنحدد عنوان URL لخادم وكيل في 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 في دوال السحابة.

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

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

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

461e9bae74227fc1.png

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

3adb01644217578c.png

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

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

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

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

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