
كان لدينا نموذجان من google ، و 75 سؤالًا في كل منهما ، و 5 من مستخدمي الأعمال الذين قاموا بتحرير هذه النماذج بشكل نشط ، وأيضًا برنامج نصي من google لتصدير النموذج إلى JSON. ليس من الصعب تشغيله في كل مرة بيديك ، ولكن بمجرد البدء في أتمتة عملك ، ثم انتقل إلى هذه الهواية.
في الوثائق الرسمية ، سوف يكسر الشيطان ساقه ، لذلك تحت القط سنلقي نظرة فاحصة على التنزيل عن بُعد وإطلاق Google Apps Script من خلال واجهة برمجة تطبيقات REST باستخدام Python.
مقدمة
في Doctor Near ، نقوم بتطوير نظام أساسي لبرامج الدردشة ، حيث يتم استخدام نماذج Google لوصف السيناريوهات. وفقًا لذلك ، أرغب في الحصول على JSON من النماذج بنقرة زر واحدة تحتوي على العقد (نقاط النموذج) والبيانات الوصفية لها (الانتقال بين العقد وأنواع العقد واسمها). يبدو أن الرغبة بسيطة ، لكن Google لا تدعم هذه الوظيفة وعليك تجميع هذا "المصدر" بيديك. النظر في الخطوات اللازمة لإنشائه.
الخطوة 1. النص البرمجي لتطبيقات Google
وفرت Google القدرة على التفاعل مع خدماتها (الأوراق والمستندات والنماذج) من خلال Google Apps Script - البرامج النصية المكتوبة بلغة google script (.gs). لا تقدم هذه المقالة تحليلًا للغة النص البرمجي لـ google ، لذا سأقدم مثالًا على برنامج نصي جاهز يقوم بإنشاء JSON من نموذج Google موجود. تم أخذ
رمز المستخدم
Steven Schmatz من github كأساس ، والذي أعرب عن امتناني له.
ما يحدث في الكود:
- دالة getFormMetadata - تقوم بإرجاع JSON مع بيانات تعريف النموذج
- دالة itemToObject - تحول الكائن form.item إلى JSON مع الحقول المطلوبة
- وظيفة sendEmail - ترسل ملف JSON إلى البريد المحدد في النص
- الوظيفة الرئيسية - إرجاع الناتج JSON
- المتغير form_url في الوظيفة الرئيسية هو عنوان نموذج google الخاص بنا
الخطوة 2. اختبار البرنامج النصي
في الوقت الحالي ، يمكن التحقق من أداء البرنامج النصي على النحو التالي:
- إنشاء مشروع البرنامج النصي التطبيق الخاص بك
- انسخ الكود فيه
- بدلاً من <YOUR_FORM_URL> نستبدل عنوان النموذج الخاص بنا للنموذج docs.google.com/forms/d/FORM_IDENTIFICATOR/edit
- uncomment الدعوة لإرسال البريد الإلكتروني في الوظيفة الرئيسية
- بدلاً من <YOUR_EMAIL> نستبدل عنوان البريد الإلكتروني الذي نريد استلام JSON إليه
- احفظ المشروع
- تشغيل الوظيفة الرئيسية
- إذا كانت هذه هي المرحلة الأولى من البرنامج النصي ، فسيعلمك النظام بالحاجة إلى منح البرنامج النصي إذنًا لإرسال بريد إلكتروني من عنوانك. لا تخف. هذا هو الإجراء القياسي المطلوب لاختبار البرنامج النصي. انتقل إلى "أذونات المراجعة" -> حدد حسابك -> "خيارات متقدمة" -> "انتقل إلى مشروع PROJECT_NAME (غير آمن)" -> "السماح"
- في انتظار البرنامج النصي للعمل
- ابحث في صندوق البريد وشاهد ملف JSON في نموذج نصي
سيكون كل شيء على ما يرام ، ولكن الاستخدام الإضافي للبيانات التي تم الحصول عليها يتضمن النسخ اليدوي من البريد ، ومعالجة هذا النص (في بيثون ، على سبيل المثال) وحفظ الملف الناتج. لا يبدو جاهزًا جدًا للإنتاج. نحن نتمكّن من تشغيل هذا البرنامج النصي تلقائيًا والحصول على نتائجه من خلال واجهة برمجة تطبيقات Google Apps Script ، لكن أولاً أنشأنا مشروع Google وفقًا لذلك.
انتباه: لتوفير الراحة لفهم ما يحدث ، سأشير أدناه إلى صفحتين فقط ، لذلك يوصى بفتحها في علامات تبويب متجاورة:
- صفحة تحرير النص / البرنامج النصي - "الصفحة 1"
- صفحة Google Cloud Platform - "الصفحة 2"
الخطوة 3. تكوين Google Cloud Platform
نذهب إلى Google Cloud Platform (صفحة 2) ، لإنشاء مشروع جديد. من الضروري إنشاء مشروع جديد ، لأن حالة المشروع هي افتراضي ، وستاندارت مطلوبة لأغراضنا. يمكن العثور على مزيد من التفاصيل
هنا (النقطة 3).
نعود إلى الصفحة 2 ، انتقل إلى علامة التبويب "API والخدمات" ، ثم "نافذة طلب وصول OAuth". اضبط نوع المستخدم على "خارجي".
في النافذة التي تظهر ، املأ "اسم التطبيق".
افتح الصفحة الرئيسية على Google Cloud Platform. من كتلة "معلومات المشروع" نسخ رقم المشروع.
انتقل إلى الصفحة 1. افتح البرنامج النصي الذي تم إنشاؤه مسبقًا. في نافذة تحرير النصوص المفتوحة ، انتقل إلى "الموارد" -> "مشروع منصة السحاب". في حقل "تغيير المشروع" ، أدخل رقم المشروع الذي تم نسخه مسبقًا. الآن يرتبط هذا البرنامج النصي بالمشروع الذي تم إنشاؤه.
الخطوة 4. بيثون REST API
حان الوقت لأتمتة البرنامج النصي باستخدام
REST API . تم استخدام بايثون كلغة.
تطبيقات API سيناريو تسجيل الدخول
يجب أن يكون للرمز حق الوصول إلى المشروع ، وبالتالي فإن الإجراء الأول والمهم للغاية هو تسجيل الدخول في Apps Script API. افتح الصفحة 2 -> "API والخدمات" -> "بيانات الاعتماد" -> "إنشاء بيانات اعتماد" -> "معرف عميل OAuth" -> "أنواع أخرى". نحن نسمي معرفنا ، انتقل إليه. في علامة التبويب "بيانات الاعتماد" ، حدد "تنزيل ملف JSON". سيؤدي هذا إلى تحميل ملف المفتاح للوصول من الرمز إلى المشروع في Google. نضع هذا الملف في مجلد بيانات الاعتماد.
تحتاج الآن إلى منح إذن لاستخدام واجهة برمجة التطبيقات (في حالتنا ، واجهة برمجة تطبيقات Apps) كجزء من هذا المشروع. للقيام بذلك ، انتقل إلى "API والخدمات" -> "المكتبة" -> اكتب "Apps Script API" في البحث وانقر على "تمكين".
تحتوي التطبيقات التي تتفاعل مع Google على مجموعة من الأذونات التي يجب على المستخدم منحها عند تشغيله. تعتمد هذه النسخة على الوظائف التي يستخدمها برنامج نصي معين ويمكنك العثور عليها بالانتقال إلى الصفحة 1 في نافذة تحرير البرنامج النصي في "ملف" -> "خصائص المشروع" -> "النطاقات". يجب حفظ هذه الأذونات للاستخدام المستقبلي في التعليمات البرمجية.
في هذه الحالة ، ستبدو وظيفة تسجيل الدخول كما يلي:
import pickle import os.path from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request def login(config): try: creds = None
تعتبر مجموعة التعليمات البرمجية هذه الإجراء القياسي لبدء استخدام Google App Script.
نستخدم رمز المصادقة ، ومن خلال تسجيل الدخول ، إما إنشاء رمز مميز جديد أو استخدام رمز موجود.
للراحة ، تم إنشاء ملف تكوين JSON ، والذي يحتوي على النموذج التالي:
{ "SCOPES": ["https://www.googleapis.com/auth/forms", "https://www.googleapis.com/auth/script.send_mail"], "credentials_path": "credentials/", "credentials_file": "google_test_project.json", "token_file": "token.pickle" }
هام: يتم إنشاء الرمز المميز للمصادقة مع نطاق معين من الأذونات. بمعنى آخر ، عند تغيير نطاق الأذونات ، يجب عليك حذف الرمز المميز وإنشاء رمز جديد عند تسجيل الدخول.
رمز البرنامج النصي للتحديث عن بعد
الآن سوف نتعلم كيفية تحديث رمز البرنامج النصي عن بعد ، ثم تشغيل هذا الرمز والحصول على النتيجة. في الواقع ، بالإضافة إلى الشفرة التي نديرها في محرر Google ، يوجد أيضًا
ملف بيان يحتوي على حقوق التشغيل ، وإعدادات النشر ، إلخ. مزيد من المعلومات حول هيكلها يمكن العثور عليها
هنا .
للاطلاع على ملف البيان الافتراضي الذي أنشأته Google للنص الخاص بك ، انتقل إلى محرر النص في "عرض" -> "إظهار ملف البيان". سيظهر البيان في قائمة الملفات المتعلقة بهذا البرنامج النصي.
لم يكن الكلام عن البيان بدون سبب: يتطلب تحديث البرنامج النصي عن بُعد تنزيل رمز الملفين (* .gs) وبيان البيان (appscript.json).
أولاً ، اقرأ رمز ملف .gs الذي نريد نشره:
with open('export-google-form.gs', 'r') as f: sample_code = f.read()
الآن قم بنسخ البيان الذي تم إنشاؤه تلقائيًا وقم بتعديله قليلاً لأغراضنا. تصف الوثائق بشكل شامل هيكل ملف البيان ، لذلك لن أتناول هذه النقطة. لكي يعمل البرنامج النصي ، تحتاج إلى إضافة قسم "implementationApi" إلى البيان الافتراضي المطلوب لتشغيل البرنامج النصي عن بُعد من خلال واجهة برمجة التطبيقات. في هذا القسم ، نشير إلى دائرة الأشخاص الذين لديهم القدرة على تشغيلها. لقد سمحت بالتشغيل لجميع الذين حصلوا على ترخيص ، والذي يتوافق مع معرف "أي شخص":
MANIFEST = ''' { "timeZone": "America/New_York", "exceptionLogging": "STACKDRIVER", "executionApi": { "access": "ANYONE" } } '''.strip()
يجب أن يحتوي نص طلب التحديث على مجموعة من الملفات بالهيكل التالي:
- الاسم : اسم الملف المراد إنشاؤه على الخادم ، دون امتداد
- النوع : نوع الملف (JSON للبيان ، SERVER_JS for .gs)
- المصدر : رمز الملف
request = { 'files': [{ 'name': 'hello', 'type': 'SERVER_JS', 'source': sample_code }, { 'name': 'appsscript', 'type': 'JSON', 'source': MANIFEST } ] }
أخيرًا ، يجب أن يحتوي طلب التحديث نفسه على النص الأساسي (الطلب الموضح أعلاه) ومعرف البرنامج النصي. يمكن الحصول على الأخير من خلال الانتقال إلى "الملف" -> "خصائص المشروع" في محرر النصوص ونسخ "معرف البرنامج النصي":
script_id = 'qwertyuiopQWERTYUIOPasdfghjkl123456789zxcvbnmASDFGHJKL54'
بالنسبة لكائن الخدمة الذي تم الحصول عليه نتيجة لتسجيل الدخول ، نحصل على حقل المشاريع () ونستدعي طريقة updateContent () ، وبعد ذلك نسمي طريقة execute () لكائن HttpRequest المستلم:
service.projects().updateContent( body=request, scriptId=script_id ).execute()
ومع ذلك ، في الوقت الحالي ، سيؤدي تشغيل الرمز إلى حدوث خطأ:
"error": { "code": 403, "message": "Request had insufficient authentication scopes.", "status": "PERMISSION_DENIED" }
كما ترون ، لا توجد أذونات كافية في مصادقة osprey ، والتي أشرنا إليها سابقًا. ننتقل إلى الوثائق الرسمية على واجهة برمجة التطبيقات ، وهي طريقة
updateContent ، والتي استخدمناها لتحديث البرنامج النصي عن بُعد. تقول الوثائق أن استخدام هذه الطريقة يتطلب تمكين الوصول إلى script.projects:
https://www.googleapis.com/auth/script.projects
قم بإضافته إلى ملف التكوين الخاص بنا في قسم SCOPES. كما كتبت أعلاه ، عند تغيير osprey ، من الضروري حذف الرمز المميز الذي تم إنشاؤه تلقائيًا.
! ممتاز في الوقت الحالي ، تعلمنا تحديث برنامج Google النصي عن بُعد. يبقى لتشغيله والحصول على نتيجة التنفيذ.
تشغيل البرنامج النصي
يحتوي طلب
بدء تشغيل البرنامج النصي على scriptID والنصوص بالهيكل التالي:
- الوظيفة : اسم الوظيفة التي نريد تشغيلها
- المعلمات : (اختياري) مجموعة من المعلمات من النوع البدائي (سلسلة ، صفيف ...) تنتقل إلى الوظيفة
- sessionState : (اختياري) مطلوب فقط لتطبيقات Android
- devMode : (اختياري) صحيح إذا كان المستخدم هو مالك البرنامج النصي ، ثم سيتم إطلاق الإصدار الأحدث من الإصدار الذي تم نشره باستخدام Apps Script API. (افتراضيا - خطأ)
من أجل عدم خياطة عنوان URL لنموذج Google في البرنامج النصي ، سنقوم بتمرير
form_url إلى الوظيفة
الرئيسية كوسيطة.
تحذير. عندما اختبرنا البرنامج النصي ، لم تقبل الوظيفة
الرئيسية أي شيء ، لذلك سنقوم بتغيير الأسطر الأولى من التعليمات البرمجية في ملف .gs كما يلي:
function main(form_url) { var form = FormApp.openByUrl(form_url); .......
نظرًا لأن تطبيقنا ليس لنظام Android ونحن أصحاب البرنامج النصي ، فسيبدو الجسم كما يلي:
body = { "function": "main", "devMode": True, "parameters": form_url }
قم بتشغيل البرنامج النصي واكتب نتيجة التنفيذ إلى متغير resp:
resp = service.scripts().run(scriptId=script_id, body=body).execute()
حفظ resp إلى ملف بتنسيق JSON مناسب:
import json with open('habr_auto.json', 'w', encoding='utf-8') as f: json.dump(resp['response']['result'], f, ensure_ascii=False, indent=4)
تحذير. بسبب حقيقة أن طلب script.run () ينتظر النتيجة عبر مأخذ التوصيل ، عندما يتم تجاوز المهلة بحلول وقت التنفيذ ، سيحدث خطأ من النوع التالي:
socket.timeout: The read operation timed out
لتجنب هذا السلوك ، أوصي في بداية البرنامج بتعيين حد لوقت مأخذ التوصيل المفتوح ، وهو ما يكفي بوضوح لانتظار انتهاء البرنامج النصي للتنفيذ. في حالتي ، 120 ثانية تكفي:
import socket socket.setdefaulttimeout(120)
فويلا! خط أنابيب مناسب للتحديث عن بعد وإطلاق البرامج النصية من Google جاهز. ويرد رمز كامل تكييفها لاطلاق من المحطة في
جيثب بلدي.
أيضا ، سأقدم رمز الوظائف الرئيسية أدناه
login.py from pprint import pprint import pickle import os.path from googleapiclient.discovery import build from google_auth_oauthlib.flow import InstalledAppFlow from google.auth.transport.requests import Request def login(config): try: creds = None
update_script.py from pprint import pprint import json import sys from googleapiclient import errors from google_habr_login import login MANIFEST = ''' { "timeZone": "America/New_York", "exceptionLogging": "STACKDRIVER", "executionApi": { "access": "ANYONE" } } '''.strip() def update_project(service, script_id, script_file_name):
export_form.py from pprint import pprint import socket import json import sys from googleapiclient import errors from google_habr_login import login socket.setdefaulttimeout(120)
للبدء ، تحتاج إلى وضع ملف JSON مع مفاتيح الوصول إلى Google في مجلد بيانات الاعتماد ، وتهيئة JSON في نفس الدليل مثل البرامج النصية.
ثم ، إذا كنا نريد تحديث البرنامج النصي عن بُعد ، فعند اتصال المحطة الطرفية:
python update_script.py <config_file_name> <script_id> <script_file_name>
في هذه الحالة:
- config_file_name - اسم ملف التكوين JSON
- script_id - معرف البرنامج النصي
- script_file_name - اسم ملف .gs الذي سيتم تحميله إلى google
لتشغيل البرنامج النصي ، اتصل:
python export_form.py <config_file_name> <result_file_name> <script_id> <google_form_url>
في هذه الحالة:
- config_file_name - اسم ملف التكوين JSON
- result_file_name - اسم ملف JSON الذي سيتم فيه إلغاء تحميل النموذج
- script_id - معرف البرنامج النصي
- google_form_url - google form url
شكرا لاهتمامكم ، في انتظار اقتراحاتكم وتعليقاتكم :)