ساخت یک برنامه کاربردی وب دسترسی به دستگاه

۱. مقدمه

برنامه دسترسی به دستگاه، رابط برنامه‌نویسی کاربردی مدیریت دستگاه هوشمند (Smart Device Management API) را ارائه می‌دهد، یک رابط برنامه‌نویسی کاربردی REST برای توسعه‌دهندگان تا بتوانند دستگاه‌های Google Nest را از برنامه‌های خود کنترل کنند. کاربران باید برای دسترسی شخص ثالث به دستگاه‌های Nest خود رضایت دهند.

52f77aa38cda13a6.png

سه مرحله کلیدی برای یکپارچه‌سازی موفقیت‌آمیز دسترسی به دستگاه وجود دارد:

  1. ایجاد پروژه - یک پروژه در پلتفرم ابری گوگل ایجاد کنید و به عنوان توسعه‌دهنده در کنسول دسترسی به دستگاه ثبت‌نام کنید.
  2. پیوند حساب - کاربران را از طریق جریان پیوند حساب هدایت کرده و یک کد دسترسی دریافت کنید. کد را با یک توکن دسترسی مبادله کنید.
  3. کنترل دستگاه - با ارسال دستورات به همراه توکن دسترسی، درخواست‌های API مدیریت هوشمند دستگاه را برای کنترل دستگاه‌ها ارسال کنید.

در این Codelab، با ساخت یک برنامه وب که احراز هویت را مدیریت می‌کند و فراخوانی‌های API مدیریت هوشمند دستگاه، به طور عمیق به نحوه کار دسترسی به دستگاه خواهیم پرداخت. همچنین، استقرار یک سرور پروکسی ساده با استفاده از Node.js و Express را برای مسیریابی درخواست‌های دسترسی به دستگاه بررسی خواهیم کرد.

قبل از شروع، خوب است که با فناوری‌های رایج وب که در این Codelab استفاده خواهیم کرد، مانند احراز هویت با OAuth 2.0 یا ساخت یک برنامه وب با Node.js ، آشنا شوید، هرچند که اینها پیش‌نیاز نیستند.

آنچه نیاز دارید

  • Node.js نسخه ۸ یا بالاتر
  • حساب گوگل با ترموستات نست (Nest Thermostat) مرتبط

آنچه یاد خواهید گرفت

  • راه‌اندازی یک پروژه Firebase برای میزبانی صفحات وب استاتیک و توابع ابری
  • صدور درخواست‌های دسترسی به دستگاه از طریق یک برنامه وب مبتنی بر مرورگر
  • ساخت یک سرور پروکسی با Node.js و Express برای مسیریابی درخواست‌های شما

۲. ایجاد پروژه

توسعه‌دهندگان باید یک پروژه Google Cloud Platform (GCP) ایجاد کنند تا بتوانند یکپارچه‌سازی دسترسی به دستگاه (Device Access) را راه‌اندازی کنند. شناسه کلاینت (Client Id) و راز کلاینت (Client Secret) که در پروژه GCP ایجاد می‌شوند، به عنوان بخشی از جریان OAuth بین برنامه توسعه‌دهنده و Google Cloud استفاده خواهند شد. توسعه‌دهندگان همچنین باید برای ایجاد یک پروژه جهت دسترسی به رابط برنامه‌نویسی کاربردی (API) مدیریت دستگاه هوشمند (Smart Device Management API) به کنسول دسترسی به دستگاه (Device Access Console) مراجعه کنند.

پلتفرم ابری گوگل

به پلتفرم ابری گوگل بروید. روی ایجاد یک پروژه جدید کلیک کنید و نام پروژه را وارد کنید. شناسه پروژه [GCP-Project-Id] برای گوگل کلود نیز نمایش داده خواهد شد، لطفاً آن را یادداشت کنید زیرا در طول راه‌اندازی فایربیس از آن استفاده خواهیم کرد. (ما در سراسر این آزمایشگاه کد به این شناسه [GCP-Project-Id] خواهیم گفت.)

585e926b21994ac9.png

اولین قدم فعال کردن کتابخانه API لازم در پروژه ما است. به APIها و خدمات > کتابخانه بروید و API مدیریت دستگاه هوشمند را جستجو کنید. برای مجوز دادن به پروژه خود برای ارسال درخواست به فراخوانی‌های API دسترسی به دستگاه، باید این API را فعال کنید.

14e7eabc422c7fda.png

قبل از اینکه به سراغ ایجاد اعتبارنامه‌های OAuth برویم، باید صفحه رضایت OAuth را برای پروژه خود پیکربندی کنیم. به APIها و خدمات > صفحه رضایت OAuth بروید. برای نوع کاربر ، خارجی را انتخاب کنید. یک نام و یک ایمیل پشتیبانی برای برنامه خود و همچنین اطلاعات تماس توسعه‌دهنده را برای تکمیل صفحه اول ارائه دهید. وقتی از شما خواسته شد کاربران آزمایشی را آزمایش کنید ، در این مرحله حتماً آدرس ایمیل با دستگاه‌های مرتبط را ارائه دهید.

پس از پیکربندی صفحه رضایت OAuth، به APIها و خدمات > اعتبارنامه‌ها بروید. روی +ایجاد اعتبارنامه‌ها کلیک کنید و شناسه کلاینت OAuth را انتخاب کنید. برای نوع برنامه، برنامه وب را انتخاب کنید.

5de534212d44fce7.png

یک نام برای کلاینت خود وارد کنید و روی CREATE کلیک کنید. بعداً یک Authorized JavaScript origin و Authorized redirect URI اضافه خواهیم کرد. تکمیل این فرآیند، [Client-Id] و [Client-Secret] مرتبط با این کلاینت OAuth 2.0 را نمایش می‌دهد.

e6a670da18952f08.png

کنسول دسترسی به دستگاه

به کنسول دسترسی به دستگاه بروید. اگر قبلاً از کنسول دسترسی به دستگاه استفاده نکرده‌اید، با توافقنامه شرایط خدمات و هزینه ثبت نام ۵ دلاری مواجه خواهید شد.

یک پروژه جدید ایجاد کنید و نامی برای آن تعیین کنید. در پنجره بعدی، [Client-Id] که در مرحله قبل از GCP دریافت کردید را وارد کنید.

f8a3f27354bc2625.png

فعال کردن رویدادها و تکمیل مراحل ایجاد پروژه، شما را به صفحه اصلی پروژه‌تان می‌برد. [شناسه پروژه] شما تحت نامی که به پروژه خود داده‌اید، فهرست خواهد شد.

db7ba33d8b707148.png

لطفاً [شناسه-پروژه] خود را یادداشت کنید زیرا ما هنگام ارسال درخواست‌ها به رابط برنامه‌نویسی کاربردی مدیریت دستگاه هوشمند از آن استفاده خواهیم کرد.

۳. تنظیمات فایربیس

فایربیس به توسعه‌دهندگان روشی سریع و آسان برای استقرار برنامه‌های وب ارائه می‌دهد. ما یک برنامه وب سمت کلاینت برای ادغام دسترسی به دستگاه با استفاده از فایربیس توسعه خواهیم داد.

ایجاد یک پروژه فایربیس

به کنسول فایربیس بروید. روی «افزودن پروژه» کلیک کنید، سپس پروژه‌ای را که در مرحله ایجاد پروژه ایجاد کرده‌اید انتخاب کنید. این یک پروژه فایربیس ایجاد می‌کند که به پروژه GCP شما [GCP-Project-Id] پیوند داده می‌شود.

پس از ایجاد موفقیت‌آمیز پروژه Firebase، باید صفحه زیر را مشاهده کنید:

dbb02bbacac093f5.png

نصب ابزارهای فایربیس

فایربیس مجموعه‌ای از ابزارهای رابط خط فرمان (CLI) را برای ساخت و استقرار برنامه شما فراهم می‌کند. برای نصب این ابزارها، یک پنجره ترمینال جدید باز کنید و دستور زیر را اجرا کنید. این کار ابزارهای فایربیس را به صورت سراسری نصب می‌کند.

$ npm i -g firebase-tools

برای تأیید نصب صحیح ابزارهای فایربیس، اطلاعات نسخه را بررسی کنید.

$ firebase --version

شما می‌توانید با استفاده از دستور login و با استفاده از حساب کاربری گوگل خود، وارد ابزارهای Firebase CLI شوید.

$ firebase login

راه‌اندازی اولیه پروژه میزبانی

وقتی توانستید وارد سیستم شوید، مرحله بعدی راه‌اندازی اولیه یک پروژه میزبانی برای برنامه وب شماست. از طریق ترمینال، به پوشه‌ای که می‌خواهید پروژه خود را در آن ایجاد کنید بروید و دستور زیر را اجرا کنید:

$ firebase init hosting

فایربیس برای شروع یک پروژه میزبانی وب، مجموعه‌ای از سوالات را از شما می‌پرسد:

  1. لطفا یک گزینه را انتخاب کنید — از یک پروژه موجود استفاده کنید
  2. یک پروژه پیش‌فرض Firebase برای این دایرکتوری انتخاب کنید — Select***[GCP-Project-Id]***
  3. می‌خواهید از چه چیزی به عنوان دایرکتوری عمومی خود استفاده کنید؟ — عمومی
  4. به عنوان یک برنامه تک صفحه‌ای پیکربندی شود؟ — بله
  5. آیا می‌توانم ساخت و استقرار خودکار را با گیت‌هاب تنظیم کنم؟ — خیر

پس از راه‌اندازی اولیه پروژه، می‌توانید آن را با دستور زیر در فایربیس مستقر کنید:

$ firebase deploy

فایربیس پروژه شما را اسکن کرده و فایل‌های لازم را در هاست ابری مستقر می‌کند.

fe15cf75e985e9a1.png

وقتی آدرس میزبانی وب را در مرورگر باز می‌کنید، باید صفحه‌ای را که اخیراً مستقر کرده‌اید، مشاهده کنید:

e40871238c22ebe2.png

حالا که اصول اولیه‌ی نحوه‌ی استقرار یک صفحه وب با Firebase را می‌دانید، بیایید به سراغ استقرار نمونه‌ی Codelab خود برویم!

۴. نمونه کدلب

شما می‌توانید مخزن codelab که در GitHub میزبانی می‌شود را با استفاده از دستور زیر کلون کنید:

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

در این مخزن، نمونه‌ها را در دو پوشه جداگانه ارائه می‌دهیم. پوشه codelab-start حاوی فایل‌های لازم برای شروع کار شما از نقطه فعلی در این Codelab است. پوشه codelab-done شامل نسخه کاملی از این Codelab به همراه کلاینت و سرور node.js با عملکرد کامل است.

ما در طول این codelab از فایل‌های پوشه codelab-start استفاده خواهیم کرد، هرچند اگر در هر زمانی احساس کردید که مشکلی دارید، می‌توانید به نسخه codelab-done نیز مراجعه کنید.

فایل‌های نمونه Codelab

ساختار فایل پوشه codelab-start به صورت زیر است:

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

پوشه عمومی (Public) شامل صفحات استاتیک برنامه ما است. firebase.json مسئول مسیریابی درخواست‌های وب به برنامه ما است. در نسخه codelab-done ، یک پوشه functions نیز مشاهده خواهید کرد که شامل منطق سرور پروکسی ما (express) برای استقرار در توابع Google Cloud است.

نمونه Codelab را مستقر کنید

فایل‌های موجود در codelab-start را در پوشه پروژه خود کپی کنید.

$ firebase deploy

پس از اتمام استقرار Firebase، باید بتوانید برنامه Codelab را مشاهده کنید:

e84c1049eb4cca92.png

شروع جریان احراز هویت نیاز به اعتبارنامه‌های همکار دارد که در بخش بعدی به آن خواهیم پرداخت.

۵. مدیریت OAuth

OAuth استاندارد وب برای تفویض دسترسی است که معمولاً برای اعطای دسترسی به اطلاعات حساب کاربری توسط کاربران به برنامه‌های شخص ثالث بدون اشتراک‌گذاری رمز عبور استفاده می‌شود. ما از OAuth 2.0 برای فعال کردن دسترسی توسعه‌دهندگان به دستگاه‌های کاربران از طریق Device Access استفاده می‌کنیم.

7ee31f5d9c37f699.png

مشخص کردن آدرس تغییر مسیر (URI)

اولین مرحله از جریان OAuth شامل ارسال مجموعه‌ای از پارامترها به نقطه پایانی Google OAuth 2.0 است. پس از دریافت رضایت کاربر، سرورهای Google OAuth درخواستی با کد مجوز به Redirect URI شما ارسال می‌کنند.

ثابت SERVER_URI (خط ۱۹) را با آدرس میزبانی وب خودتان در scripts.js به‌روزرسانی کنید:

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

با اجرای مجدد برنامه با این تغییر، Redirect URI مورد استفاده برای پروژه شما به‌روزرسانی خواهد شد.

$ firebase deploy

فعال کردن ریدایرکت URI

پس از به‌روزرسانی Redirect URI در فایل اسکریپت‌ها، باید آن را به لیست Redirect URI های مجاز برای Client Id که برای پروژه خود ایجاد کرده‌اید، اضافه کنید. به صفحه Credentials در Google Cloud Platform بروید، که تمام اعتبارنامه‌های ایجاد شده برای پروژه شما را فهرست می‌کند:

۱a07b624b5e548da.png

در زیر لیست شناسه‌های کلاینت OAuth 2.0 ، شناسه کلاینتی را که در مرحله ایجاد پروژه ایجاد کرده‌اید، انتخاب کنید. URI تغییر مسیر برنامه خود را به لیست URIهای تغییر مسیر مجاز برای پروژه خود اضافه کنید.

6d65b298e1f005e2.png

ورود به سیستم را امتحان کنید!

به آدرس میزبانی وب (Hosting URL) که با Firebase تنظیم کرده‌اید بروید، اطلاعات کاربری شریک خود را وارد کنید و روی دکمه SIGN IN کلیک کنید. شناسه کلاینت (Client Id) و رمز کلاینت (Client Secret) اطلاعات کاربری هستند که از Google Cloud Platform دریافت کرده‌اید، شناسه پروژه (Project Id) از Device Access Console گرفته شده است.

78b48906a2dd7c05.png

دکمه ورود (SIGN IN) کاربران شما را از طریق جریان OAuth برای شرکت شما، از صفحه ورود به حساب Google آنها، هدایت می‌کند. پس از ورود، از کاربران خواسته می‌شود مجوزهایی را برای دسترسی پروژه شما به دستگاه‌های Nest خود ارائه دهند.

e9b7887c4ca420.png

از آنجایی که این یک برنامه‌ی آزمایشی است، گوگل قبل از صدور ریدایرکت، هشداری صادر خواهد کرد!

b227d510cb1df073.png

روی «پیشرفته» کلیک کنید، سپس «برو به web.app (ناامن)» را انتخاب کنید تا تغییر مسیر به برنامه شما تکمیل شود.

673a4fd217e24dad.png

این یک کد OAuth را به عنوان بخشی از درخواست GET ورودی ارائه می‌دهد که سپس برنامه آن را با یک Access Token و یک Refresh Token تعویض می‌کند.

۶. کنترل دستگاه

برنامه نمونه Device Access از فراخوانی‌های Smart Device Management REST API برای کنترل دستگاه‌های Google Nest استفاده می‌کند. این فراخوانی‌ها شامل ارسال توکن دسترسی در هدر یک درخواست GET یا POST، به همراه یک payload مورد نیاز برای دستورات خاص است.

ما یک تابع درخواست دسترسی عمومی برای مدیریت این فراخوانی‌ها نوشتیم. با این حال، شما باید نقطه پایانی صحیح و همچنین شیء payload را در صورت نیاز، به این تابع ارائه دهید!

function deviceAccessRequest(method, call, localpath, payload = null) {...}
  • متد - نوع درخواست HTTP ( GET یا POST)
  • فراخوانی - رشته‌ای که نشان‌دهنده فراخوانی API ما است و برای مسیریابی پاسخ‌ها ( listDevices ، thermostatMode ، temperatureSetpoint ) استفاده می‌شود.
  • localpath — نقطه پایانی که درخواست به آن ارسال می‌شود، شامل شناسه پروژه و شناسه دستگاه (که پس از https://smartdevicemanagement.googleapis.com/v1 اضافه شده است)
  • بار مفید (*) — داده‌های اضافی مورد نیاز برای فراخوانی API (برای مثال، یک مقدار عددی که نشان‌دهنده دما برای یک نقطه تنظیم است)

ما کنترل‌های رابط کاربری نمونه (لیست دستگاه‌ها، تنظیم حالت، تنظیم دما) را برای کنترل ترموستات Nest خواهیم ساخت:

86f8a193aa397421.png

این کنترل‌های رابط کاربری، توابع مربوطه ( listDevices() ، postThermostatMode() ، postTemperatureSetpoint() ) را از scripts.js فراخوانی می‌کنند. آن‌ها برای پیاده‌سازی شما خالی گذاشته شده‌اند! هدف، انتخاب متد/مسیر صحیح و ارسال payload به تابع deviceAccessRequest(...) است.

فهرست دستگاه‌ها

ساده‌ترین فراخوانی دسترسی به دستگاه، listDevices است. این فراخوانی از یک درخواست GET استفاده می‌کند و نیازی به payload ندارد. نقطه پایانی باید با استفاده از projectId ساختاردهی شود. تابع listDevices() خود را به صورت زیر تکمیل کنید:

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

تغییرات خود را ذخیره کنید و پروژه Firebase خود را دوباره با دستور زیر مستقر کنید:

$ firebase deploy

پس از نصب نسخه جدید برنامه، صفحه را مجدداً بارگذاری کنید و روی «لیست دستگاه‌ها» کلیک کنید. این باید لیستی را در قسمت «کنترل دستگاه» نمایش دهد که در آن باید شناسه ترموستات خود را ببینید:

b64a198673ed289f.png

انتخاب دستگاه‌ها از لیست، فیلد deviceId را در فایل scripts.js به‌روزرسانی می‌کند. برای دو کنترل بعدی، باید deviceId را برای دستگاه خاصی که می‌خواهیم کنترل کنیم، مشخص کنیم.

کنترل ترموستات

دو ویژگی برای کنترل اولیه ترموستات Nest در API مدیریت دستگاه هوشمند وجود دارد. ThermostatMode و TemperatureSetpoint . ThermostatMode حالت ترموستات Nest شما را روی یکی از چهار حالت مختلف ممکن تنظیم می‌کند: {خاموش، گرما، سرما، گرما-سرما}. سپس باید حالت انتخاب شده را به عنوان بخشی از بار مفید ارائه دهیم.

تابع 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 شما مدیریت می‌کند. دو پارامتر وجود دارد که می‌توانند در payload تنظیم شوند، 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);
}

۷. سرور Node.js (اختیاری)

تبریک! شما یک برنامه وب سمت کلاینت ساخته‌اید که می‌تواند درخواست‌های API مدیریت دستگاه هوشمند را از یک مرورگر ارسال کند. برای آن دسته از شما که می‌خواهید در سمت سرور بسازید، می‌خواهیم تلاش شما را با یک سرور پروکسی که می‌تواند درخواست‌های شما را از مرورگر هدایت کند، آغاز کنیم.

برای این سرور پروکسی، از توابع ابری Firebase، Node.js و Express استفاده خواهیم کرد.

مقداردهی اولیه توابع ابری

یک پنجره ترمینال جدید باز کنید، به دایرکتوری پروژه خود بروید و موارد زیر را اجرا کنید:

$ firebase init functions

فایربیس برای مقداردهی اولیه توابع ابری، مجموعه‌ای از سوالات را از شما می‌پرسد:

  1. برای نوشتن توابع ابری از چه زبانی استفاده می‌کنید؟ — جاوا اسکریپت
  2. آیا می‌خواهید از ESLint برای شناسایی اشکالات احتمالی و اعمال سبک استفاده کنید؟ — خیر
  3. آیا می‌خواهید همین الان وابستگی‌ها را با npm نصب کنید؟ — بله

این کار باعث راه‌اندازی اولیه پوشه functions در پروژه شما و همچنین نصب وابستگی‌های لازم می‌شود. خواهید دید که پوشه پروژه شما شامل یک پوشه functions، به همراه یک فایل index.js برای تعریف توابع ابری ما، package.json برای تعریف تنظیمات و یک پوشه node_modules برای نگهداری وابستگی‌ها است.

ما از دو کتابخانه npm برای ساخت قابلیت‌های سمت سرور استفاده خواهیم کرد: express و xmlhttprequest. شما باید ورودی‌های زیر را به لیست وابستگی‌ها در فایل package.json اضافه کنید:

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

سپس اجرای دستور npm install از دایرکتوری functions باید وابستگی‌های پروژه شما را نصب کند:

$ npm install

در صورتی که npm در دانلود بسته‌ها با مشکل مواجه شود، می‌توانید xmlhttprequest را ذخیره کرده و با دستور زیر آن را به طور صریح بیان کنید:

$ npm install express xmlhttprequest --save

ارتقا به طرح Blaze

استفاده از دستور firebase deploy مستلزم ارتقا به طرح Blaze است که مستلزم اضافه کردن یک روش پرداخت به حساب کاربری شما می‌باشد. به نمای کلی پروژه > استفاده و صورتحساب بروید و مطمئن شوید که طرح Blaze را برای پروژه خود انتخاب کرده‌اید.

c6a5e5a21397bef6.png

ساخت سرور اکسپرس

یک سرور اکسپرس از یک چارچوب ساده برای پاسخ به درخواست‌های ورودی GET و POST پیروی می‌کند. ما یک سرولت ساخته‌ایم که به درخواست‌های POST گوش می‌دهد، آنها را به یک URL مقصد مشخص شده در payload منتقل می‌کند و با پاسخی که از انتقال دریافت می‌شود، پاسخ می‌دهد.

فایل index.js خود را در دایرکتوری functions به شکل زیر تغییر دهید:

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 شروع می‌شوند را به سرور اکسپرس ما هدایت می‌کند و بقیه آدرس‌ها به index.html ما می‌روند.

فراخوانی‌های API پروکسی

حالا که سرورمان آماده است، بیایید یک آدرس پروکسی (proxy URI) در scripts.js تعریف کنیم تا مرورگرمان درخواست‌ها را به این آدرس ارسال کند:

const PROXY_URI = SERVER_URI + "/proxy";

سپس یک تابع proxyRequest به نام scripts.js اضافه کنید که امضایی مشابه تابع deviceAccessRequest(...) برای فراخوانی‌های غیرمستقیم Device Access دارد.

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 on Cloud Functions استفاده می‌کند.

مجوزهای عملکرد ابری را ارائه دهید

آخرین مرحله، بررسی مجوزهای دسترسی برای توابع ابری شما و اطمینان از این است که برنامه سمت کلاینت شما قادر به فراخوانی آنها خواهد بود.

از پلتفرم ابری گوگل، از منو به تب توابع ابری بروید، سپس تابع ابری خود را انتخاب کنید:

461e9bae74227fc1.png

روی مجوزها (Permissions ) و سپس افزودن عضو (Add Member) کلیک کنید. در فیلد عضو جدید، عبارت allUsers را بنویسید و Cloud Functions > Cloud Functions Invoker را به عنوان نقش انتخاب کنید. با کلیک روی ذخیره (Save)، یک پیام هشدار نمایش داده می‌شود:

3adb01644217578c.png

انتخاب گزینه «اجازه دسترسی عمومی» باعث می‌شود برنامه سمت کلاینت شما بتواند از عملکرد ابری شما استفاده کند.

تبریک می‌گوییم - شما تمام مراحل را انجام داده‌اید. اکنون می‌توانید به برنامه وب خود بروید و کنترل‌های دستگاه را که از طریق سرور پروکسی شما هدایت می‌شوند، فعال کنید!

مراحل بعدی

به دنبال راه‌هایی برای گسترش تخصص خود در زمینه دسترسی به دستگاه هستید؟ برای کسب اطلاعات بیشتر در مورد کنترل سایر دستگاه‌های Nest و فرآیند صدور گواهینامه برای یادگیری مراحل عرضه محصول خود به جهان، مستندات مربوط به ویژگی‌ها (traits) را بررسی کنید!

مهارت‌های خود را با نمونه برنامه کاربردی وب Device Access ارتقا دهید، جایی که بر اساس تجربه Codelab خود، یک برنامه کاربردی وب کارآمد را برای کنترل دوربین‌های Nest، زنگ درها و ترموستات‌ها مستقر خواهید کرد.