تُفتح لوحة المعلومات بلا مشكلة في المتصفح على الحاسوب المحمول، بينما يفشل نص جدول البيانات نفسه بخطأ في عدم إتاحة العنوان. لا يغيّر تشغيل VPN أو إيقافه شيئًا، لأن الطلب لا يغادر الحاسوب المحمول إطلاقًا. ينفّذ Apps Script على بنية Google التحتية ويفتح اتصاله الخاص من هناك. هذه الحقيقة الواحدة تحدد التصميم كله.

افصل بين سؤالين قبل تغيير أي شيء: أي جهاز يرسل الطلب، وأي وثيقة اعتماد يقبلها المستقبل.

الطلب لا يبدأ أبدًا على حاسوبك المحمول

يرسل تبويب المتصفح من الحاسوب المحمول، عبر محوّل VPN ولاحقة DNS الداخلية وإلى الشبكة الفرعية الخاصة. يرسل UrlFetchApp من مضيف تديره Google، لذا يرى مخدّمات الأسماء لدى Google وعناوين الخروج لدى Google ولا يرى أيًا من مسارات الأنفاق المنفصلة لديك. يشترك المساران في مستند جدول بيانات، لا في موقع شبكي. في سجل الوصول الخاص بالتطبيق تظهر محاولة النص كعنوان Google بدلًا من عنوان من مجموعة VPN، وهذا أسرع تأكيد ستحصل عليه.

لهذا لا تفعل الإصلاحات المحلية شيئًا. توجيه الحاسوب المحمول إلى مخدّم أسماء آخر، أو إعادة تشغيل عميل VPN، أو إضافة سطر في hosts، يغيّر مسار المتصفح ويترك مسار النص كما هو تمامًا.

ما يستبعده ذلك

لا يمكن الوصول من Apps Script إلى نقطة نهاية داخلية فقط، وقائمة عناوين IP المسموح بها بديل ضعيف عن ضبط الوصول في هذا الموضع. نطاقات الخروج لدى Google واسعة ومشتركة مع عملاء آخرين ويستحيل ربطها بنص واحد. ويؤكد مرجع UrlFetchApp أن الطلبات تصدر من مجموعة عناوين IP لدى Google، وهذه هي النسخة الموثوقة من ذلك الادعاء. فتح التطبيق الداخلي لتلك النطاقات يقبل حركة لا يمكنك نسبتها.

تتصرف جلسات المتصفح بالطريقة نفسها. لا ينتقل ملف تعريف ارتباط أو جلسة SSO في متصفح الحاسوب المحمول مع الطلب، وهو عميل HTTPS جديد بلا حالة جلسة. وأي شيء يعتمد على إعادة توجيه SSO في المتصفح ينتهي عند ذلك التوجيه بدلًا من بياناتك.

شكلان قابلان للتنفيذ

يمنح الشكل الأول النص واجهة API معتمدة. انشر الخدمة الداخلية خلف بوابة تتحقق من هوية المتصل، ثم اجعل النص يقدّم وثيقة اعتماد تقبلها البوابة، مثل رمز حساب خدمة. في Apps Script يعني ذلك مكتبة OAuth2 أو ScriptApp.getOAuthToken()، مع قائمة هويات متصلين مسموح بها على جانب API بدلًا من قائمة عناوين IP.

يعكس الشكل الثاني الاتجاه. تستعلم مهمة داخلية من النظام الخاص وتنشر نتيجة مضبوطة إلى Sheet أو كائن Cloud Storage أو جدول BigQuery يقرأه النص. يمكن أن تكون مهمة Cloud Run أو مجدول محلي أو خطوة ETL قائمة هي تلك المهمة، ولا يحتاج أي منها إلى قبول اتصال وارد. عندئذ يستهلك جدول البيانات مجموعة بيانات بدلًا من واجهة.

أي شكل يفوز يعتمد على حداثة البيانات، والتحكم على مستوى الحقل، ومن يجب أن يستطيع تدقيق القارئ.

ما يجب أن تحتويه النتيجة المنشورة

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

يحتاج اتجاه API إلى عقد أيضًا: أي وثيقة اعتماد تقبلها البوابة، وأي نطاقات يحملها الرمز، وأي هويات متصلين مسموح بها. استجابة 200 تحتوي على صفحة تسجيل دخول ليست استدعاءً ناجحًا، لذا افحص الجسم وليس رمز الحالة فقط.

اقرأ الخطأ من الجهة الصحيحة

يبلّغ Apps Script عن مضيف لا يمكن الوصول إليه كاستثناء عدم إتاحة العنوان، وهو ليس رسالة رفض الاتصال في المتصفح. يعني 403 من البوابة أن الطلب وصل وأن وثيقة اعتماد أو سياسة رُفضت. وتعني صفحة تسجيل دخول HTML أن الطلب بلغ طبقة تفاعلية لا يستطيع النص إكمالها. ثلاثة إخفاقات مختلفة بثلاثة مسؤولين مختلفين.

أبقِ سجل النص بجانب نتيجة المتصفح بدلًا من استبدال أحدهما بالآخر. يصبح السؤال المتبقي عندئذ قرار تكامل عاديًا: امنح تلك البيئة الوصول الذي تحتاجه، أو سلّمها نتيجة مضبوطة.

مقالات ذات صلة