ייבוא וייצוא פרויקטים

מכיוון שפרויקטים של Google Apps Script נמצאים ב-Google Drive, מפתחים יכולים לייבא ולייצא קוד מקור של Apps Script באמצעות Google Drive API (לא לבלבל עם Drive Service ב-Apps Script).

לדוגמה, מפתח יכול לכתוב קוד חדש ב-Apps Script במחשב המקומי שלו באמצעות עורך הקוד המועדף עליו, ולהשתמש במערכת לניהול גרסאות כמו Git כדי לשתף פעולה עם מפתחים אחרים. אחרי שהיא מסיימת את הגרסה, היא יכולה להעלות (לייבא) את הקבצים ל-Google Drive באמצעות API בארכיטקטורת REST, ואז להשתמש בהם כמו בכל פרויקט אחר של Apps Script.

אפשר לבצע שינויים בקוד בגרסאות המקומיות ולסנכרן אותם עם פרויקט Apps Script באמצעות Google Drive API. אפשר להוריד (לייצא) פרויקטים קיימים מ-Google Drive למחשב מקומי.

תכונות ומגבלות

אם אתם רוצים להשתמש ב-Google Drive API כדי לייבא או לייצא פרויקטים, חשוב שתדעו את הפרטים הבאים:

  1. קבצים של סקריפטים בצד השרת צריכים להסתיים בסיומת ‎.gs. אולי תרצו לפתח באופן מקומי באמצעות קובצי ‎ .js, אבל הקפידו לשנות את השם כך שיכלול סיומת ‎.gs לפני הייבוא ל-Google Drive.
  2. קבצים של סקריפטים בצד הלקוח צריכים להסתיים ב-‎.html. זה כולל קובצי .html,‏ .js או .css בצד הלקוח. שוב, אפשר לפתח באופן מקומי באמצעות תוספים אחרים, אבל חשוב שיהיה תוסף ‎ .html לפני הייבוא ל-Google Drive.
  3. כשמייבאים קובצי פרויקט ל-Google Drive, כל הנתונים הקיימים בקבצים האלה יימחקו. אי אפשר להוסיף או להכניס טקסט חלקי, צריך לעדכן את כל הקובץ.
  4. קבצים של סקריפטים בצד השרת צריכים להכיל JavaScript תקין. אם יש שגיאות בקובצי ה-‎ .js של השרת, קריאת העדכון של Google Drive API תיכשל עם שגיאת 5xx. כדי למנוע את הבעיה הזו, מומלץ להריץ איתור שגיאות בקוד (linting) לפני הייבוא.
  5. אי אפשר לייבא קבצים ריקים. אם תנסו להעלות קובץ ריק, הקריאה לעדכון Google Drive API תיכשל עם שגיאת ‎5xx.
  6. אפשר לייבא או לייצא רק סקריפטים עצמאיים. אי אפשר לגשת לסקריפטים שמשויכים למסמך דרך Google Drive API.
  7. אפשר לייבא או לייצא רק קוד מקור. גם משאבים כמו מאפייני פרויקט או יומנים לא נחשפים על ידי Google Drive API. אי אפשר לבצע פעולות כמו יצירת גרסאות של סקריפט, פרסום או הפעלה של הסקריפט באמצעות Google Drive API.
  8. אתם לא מוגבלים לקובץ Code.gs אחד בשרת. כדי להקל על הפיתוח, אפשר לפצל את קוד השרת לכמה קבצים. כל קובצי השרת נטענים לאותו מרחב שמות גלובלי, לכן כדאי להשתמש במחלקות JavaScript כשרוצים לספק אנקפסולציה בטוחה.

Drive API

‫Google Drive API מאפשר למפתחים לגשת לקבצים ב-Google Drive באופן פרוגרמטי. ב-API הזה נעשה שימוש ב-GET כדי להוריד קבצים וב-PUT/POST כדי להעלות קבצים. בדף הסקירה הכללית של Google Drive API אפשר למצוא מסמכים מפורטים ומדריכים להתחלה מהירה.

במדריך הזה אנחנו מתמקדים ברישום והעברה של קבצים באמצעות המשאב Files באמצעות הקריאות הבאות:

אישור

כל הבקשות ל-Google Drive API חייבות להיות מאושרות על ידי משתמש מאומת באמצעות פרוטוקול OAuth 2.0. פרטים נוספים מופיעים במאמרי העזרה בנושא הרשאת גישה ל-Google Drive API.

בנוסף להיקפים אחרים שאפליקציה עשויה להזדקק להם (כמו https://www.googleapis.com/auth/drive), כל האפליקציות שמנסות לייבא או לייצא פרויקטים של Google Apps Script צריכות לבקש את ההיקף המיוחד:

https://www.googleapis.com/auth/drive.scripts

כדי לבדוק את בקשות הדוגמה הבאות, צריך להשתמש באסימון מסוג OAuth 2.0 bearer שהתקבל מ-OAuth 2.0 Playground.

רשימת פרויקטים קיימים

כדי ליצור רשימה של כל הפרויקטים של Apps Script ב-Drive, צריך להשתמש במשאב הקבצים כדי לשלוח שאילתה לגבי קבצים עם סוג ה-MIME ‏application/vnd.google-apps.script. כדי לסנן את התגובה כך שתכלול רק קבצים שבבעלותכם, צריך לכלול את פרמטר החיפוש 'me' in owners.

זוהי דוגמה לבקשה ולתגובה שמציגה מערך של פרויקטים של Apps Script שמוחזרים באמצעות תגובת JSON.

GET https://www.googleapis.com/drive/v2/files?q=mimeType%3D'application%2Fvnd.google-apps.script'+and+'me'+in+owners
Authorization:  Bearer ya29.fakebearerstring
{
 "kind": "drive#fileList",
 "etag": "\"kjsas92/f3zGUXczKMxEB_9ZTMRFOF3d1ZU\"",
 "selfLink": "https://www.googleapis.com/drive/v2/files?q=mimeType%3D'application/vnd.google-apps.script'+and+'me'+in+owners",
 "items": [
  {
   "kind": "drive#file",
   "id": "1vi0uwcMdHsRv1YFtgq7XdiTGSdqgjIYpdQNC0A_Udn79LOhH0vYL132D",
   "etag": "\"kjsas92/MTM3MDk3ODY5ODQyNg\"",
   "selfLink": "https://www.googleapis.com/drive/v2/files/1vi0uwcMdHsRv1YFtgq7XdiTGSdqgjIYpdQNC0A_Udn79LOhH0vYL132D",
   "alternateLink": "https://script.google.com/a/google.com/d/1vi0uwcMdHsRv1YFtgq7XdiTGSdqgjIYpdQNC0A_Udn79LOhH0vYL132D/edit?usp=drivesdk",
   "iconLink": "https://ssl.gstatic.com/docs/doclist/images/icon_11_script_list.png",
   "title": "Mail merge",
   "mimeType": "application/vnd.google-apps.script",
   "description": "",
   "labels": {
    "starred": false,
    "hidden": false,
    "trashed": true,
    "restricted": false,
    "viewed": true
   },
   "createdDate": "2013-06-11T19:24:45.188Z",
   "modifiedDate": "2013-06-11T19:24:58.426Z",
   "modifiedByMeDate": "2013-06-11T19:24:58.426Z",
   "lastViewedByMeDate": "2013-06-11T19:24:58.426Z",
   "parents": [
    {
     "kind": "drive#parentReference",
     "id": "0APdyIOzo7bWDUk9PVA",
     "selfLink": "https://www.googleapis.com/drive/v2/files/1vi0uwcMdHsRv1YFtgq7XdiTGSdqgjIYpdQNC0A_Udn79LOhH0vYL132D/parents/0APdyIOzo7bWDUk9PVA",
     "parentLink": "https://www.googleapis.com/drive/v2/files/0APdyIOzo7bWDUk9PVA",
     "isRoot": true
    }
   ],
   "exportLinks": {
    "application/json": "https://script.google.com/feeds/download/export?id=1234567890abcefghijklmnopqrstuvwxyz&format=json"
   },
   "userPermission": {
    "kind": "drive#permission",
    "etag": "\"kjsas92/259X2r5DVstv1CcIQTjt_RQPSW8\"",
    "id": "me",
    "selfLink": "https://www.googleapis.com/drive/v2/files/1vi0uwcMdHsRv1YFtgq7XdiTGSdqgjIYpdQNC0A_Udn79LOhH0vYL132D/permissions/me",
    "role": "owner",
    "type": "user"
   },
   "quotaBytesUsed": "0",
   "ownerNames": [
    "John Doe"
   ],
   "owners": [
    {
     "kind": "drive#user",
     "displayName": "John Doe",
     "picture": {
      "url": "https://lh4.googleusercontent.com/-yd1rIb6Pe2Y/AAAAAAAAAAI/AAAAAAAAAGs/PP5vTuZonik/s64/photo.jpg"
     },
     "isAuthenticatedUser": true,
     "permissionId": "1234566789"
    }
   ],
   "lastModifyingUserName": "John Doe",
   "lastModifyingUser": {
    "kind": "drive#user",
    "displayName": "John Doe",
    "picture": {
     "url": "https://lh4.googleusercontent.com/-yd1rIb6Pe2Y/AAAAAAAAAAI/AAAAAAAAAGs/PP5vTuZonik/s64/photo.jpg"
    },
    "isAuthenticatedUser": true,
    "permissionId": "1234566789"
   },
   "editable": true,
   "writersCanShare": true,
   "shared": false,
   "explicitlyTrashed": true,
   "appDataContents": false
  }
 ]
}

אם אתם יודעים את מזהה הקובץ של פרויקט Apps Script, אתם יכולים לאחזר אותו ישירות באמצעות קריאה ל-API הבאה:

GET https://www.googleapis.com/drive/v2/files/1234567890abcefghijklmnopqrstuvwxyz
Authorization:  Bearer ya29.fakebearerstring

מזהה הקובץ של פרויקט לא זהה למפתח הפרויקט. מזהה הקובץ הוא המחרוזת האלפאנומרית בכתובת ה-URL של הפרויקט.

ייצוא פרויקטים מ-Drive

אחרי שמקבלים משאב File מה-API, המאפיין exportLinks יכיל כתובת URL שאפשר לשלוף ממנה את התוכן של הפרויקט כנתוני JSON. הנה דוגמה לכתובת URL כזו:

https://script.google.com/feeds/download/export?id=1234567890abcefghijklmnopqrstuvwxyz&format=json

שולחים בקשה לכתובת ה-URL הזו כדי לאחזר את התוכן של הפרויקט עצמו. מוודאים שכוללים כותרת Authorization עם אותו טוקן OAuth Bearer

הנה דוגמה לבקשה ולתשובה:

GET https://script.google.com/feeds/download/export?id=1234567890abcefghijklmnopqrstuvwxyz&format=json
Authorization:  Bearer ya29.fakebearerstring
{
  "files": [
    {
      "id":"9basdfbd-749a-4as9b-b9d1-d64basdf803",
      "name":"Code",
      "type":"server_js",
      "source":"function doGet() {\n  return HtmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n"
    },
    {
      "id":"3asf7c0d-1afb-4a9-8431-5asdfc79e7ae",
      "name":"index",
      "type":"html",
      "source":"\u003chtml\u003e\n  \u003cbody\u003e\n    Hello, world!\n  \u003c/body\u003e\n\u003c/html\u003e"
    }
  ]
}

הדוגמה הקודמת כוללת קוד של אפליקציית אינטרנט מתוך המדריך HTML Service. מוחזר מערך של Files, שלכל אחד מהם יש את 4 המאפיינים הבאים:

id מזהה פנימי של קובץ בפרויקט, שנדרש כדי להתייחס לקובץ הזה במהלך עדכונים.
name שם הקובץ בלי הסיומות, כפי שמוצג בכלי לעריכת סקריפטים.
type שני סוגי הקבצים הם server_js ו-html.
source קוד המקור המקודד שמופיע בקובץ.

ייבוא פרויקטים ל-Drive

כדי לעדכן פרויקט קיים, מבצעים קריאת HTTP PUT ל-API של הקובץ update עם fileId המתאים. בדוגמה הבאה מוצגת טרנזקציה לדוגמה של העלאת מדיה. באמצעות אחת מספריות הלקוח, האפליקציה יכולה לכלול בקלות מטא-נתונים ומדיה באותה קריאה להעלאה. הכותרת Content-Type מציינת את סוג התוכן שהועלה במקרה הזה.

PUT https://www.googleapis.com/upload/drive/v2/files/1234567890abcefghijklmnopqrstuvwxyz
Authorization:  Bearer ya29.fakebearerestring
Content-Type:  application/vnd.google-apps.script+json
{
  "files": [
    {
      "id":"9basdfbd-749a-4as9b-b9d1-d64basdf803",
      "name":"Code",
      "type":"server_js",
      "source":"function doGet() {\n  return HtmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n"
    },
    {
      "id":"3asf7c0d-1afb-4a9-8431-5asdfc79e7ae",
      "name":"index",
      "type":"html",
      "source":"\u003chtml\u003e\n  \u003cbody\u003e\n    New message!!\n  \u003c/body\u003e\n\u003c/html\u003e"
    }
  ]
}

יצירת קבצים חדשים בפרויקט

כדי ליצור קובץ חדש בפרויקט, שולחים בקשת PUT לקובץ ללא המאפיין id. אם תכללו קובץ עם מזהה לא מוכר, המערכת תציג הודעת שגיאה.

מחיקת קבצים בפרויקט

כדי למחוק קובץ מפרויקט, שולחים בקשת PUT שלא כוללת את הקובץ הזה (אבל כן כוללת את כל הקבצים האחרים בפרויקט). כל קובץ שלא יוחזר במהלך תהליך הייבוא יימחק מהשרת.

שינוי שמות של קבצים בפרויקט

כדי לשנות את השם של קובץ בפרויקט, שולחים בקשת PUT עם id קיים אבל עם name חדש. השרת מתעלם מכל ניסיון לשנות ל-type.

יצירת פרויקט חדש

כדי ליצור פרויקט חדש, שולחים בקשת POST אל קובץ insert API. בדומה לקריאה update, אפשר להשתמש בספריית לקוח כדי לכלול מטא-נתונים כמו שם הפרויקט והתיאור שלו.

זוהי דוגמה לעסקה של העלאת מדיה. כך ייצור פרויקט בשם Untitled ב-Drive. חובה לכלול את הפרמטר convert בכתובת ה-URL. כמו בקריאה update, חובה להוסיף את הכותרת Content-Type.

POST https://www.googleapis.com/upload/drive/v2/files?convert=true
Authorization:  Bearer ya29.fakebearerestring
Content-Type:  application/vnd.google-apps.script+json
{
  "files": [
    {
      "name":"Code",
      "type":"server_js",
      "source":"function doGet() {\n  return HtmlService.createHtmlOutputFromFile(\u0027index\u0027);\n}\n"
    },
    {
      "name":"index",
      "type":"html",
      "source":"\u003chtml\u003e\n  \u003cbody\u003e\n    Hello, world!!\n  \u003c/body\u003e\n\u003c/html\u003e"
    }
  ]
}