ساخت یک استارتر

این سند توضیح می‌دهد که چگونه یک آغازگر بسازید که به برنامه یا سرویس شما اجازه می‌دهد هنگام وقوع یک رویداد، به Google Workspace Studio اطلاع دهد و اجرای جریان را آغاز کند. در API، آغازگرها، workflowTriggers نامیده می‌شوند.

یک شروع‌کننده، یک جریان را آغاز می‌کند در حالی که یک مرحله ، یک وظیفه واحد در توالی وظایفی است که یک جریان را در بر می‌گیرد. با ساخت یک شروع‌کننده، شما به کاربران این امکان را می‌دهید که جریان‌های خودکاری را تنظیم کنند که به رویدادهای بلادرنگ از برنامه یا سرویس شما واکنش نشان می‌دهند.

ساخت یک شروع‌کننده شامل تعریف شروع‌کننده در فایل مانیفست افزونه و پیاده‌سازی فراخوانی‌های چرخه عمر در Google Apps Script یا راه‌اندازی شروع‌کننده با ارسال بارهای داده به نقطه پایانی API Google Workspace Studio است.

پیش‌نیازها و مجوز OAuth

برای برقراری ارتباط با نقطه پایانی API Workspace Studio، برنامه یا سرویس شما باید با استفاده از OAuth 2.0 احراز هویت شود. برنامه باید در طول احراز هویت، محدوده OAuth اختصاصی زیر را از کاربران درخواست کند:

https://www.googleapis.com/auth/workspace.studio.trigger

این دامنه به برنامه اجازه می‌دهد تا API مربوط به Workspace Studio و جریان‌های آتش‌سوزی که کاربر برای آن استارتر پیکربندی کرده است را فراخوانی کند.

دسترسی آفلاین و توکن‌های به‌روزرسانی

از آنجا که شروع‌کننده‌ها (starters) به صورت غیرهمزمان به Workspace Studio اطلاع می‌دهند که چه زمانی یک رویداد در سرویس خارجی رخ می‌دهد - که ممکن است ساعت‌ها، روزها یا ماه‌ها پس از پیکربندی یک جریان توسط کاربر رخ دهد - سرویس شما باید هنگام فراخوانی نقطه پایانی API، یک توکن دسترسی معتبر OAuth 2.0 ارائه دهد.

توکن دسترسی ارائه شده توسط گوگل در شیء رویداد افزونه (مانند هنگام پیکربندی اولیه یا درخواست‌های فراخوانی چرخه عمر) کوتاه مدت است و فقط به مدت ۱ ساعت اعتبار دارد. این توکن برای اجرای ناهمگام رویدادهای اولیه در آینده کافی نیست. برای فراخوانی API Workspace Studio در طول زمان، سرویس شما به یک توکن به‌روزرسانی آفلاین نیاز دارد تا توکن‌های دسترسی جدید را در صورت تقاضا تولید کند.

نحوه‌ی مدیریت مجوزها و دریافت توکن به‌روزرسانی، به زمان اجرای افزونه‌ی شما بستگی دارد:

  • افزونه‌های HTTP (زمان‌های اجرای جایگزین) : برای افزونه‌های HTTP، سرویس backend شما باید یک جریان مجوز OAuth 2.0 جداگانه و مستقل از مجوز افزونه داخلی پیاده‌سازی کند تا درخواست دسترسی آفلاین ( access_type=offline ) را داشته باشد و یک توکن refresh دریافت کند.

    شما می‌توانید با نمایش یک کارت ورود یا مجوز هنگام پیکربندی اولیه توسط کاربر در Workspace Studio، از کاربران بخواهید که این اتصال را تأیید کنند. برای اطلاعات بیشتر در مورد بازگرداندن کارت‌های مجوز و مدیریت جریان OAuth، به بخش «افزونه Google Workspace خود را به یک سرویس شخص ثالث متصل کنید» مراجعه کنید (Google Workspace را به عنوان سرویس شخص ثالثی که به آن متصل می‌شوید در نظر بگیرید).

    سرویس بک‌اند شما باید توکن به‌روزرسانی را به طور ایمن ذخیره کند (برای مثال، در پایگاه داده سرویس شما در کنار triggerId ) و هر زمان که رویدادی رخ می‌دهد، قبل از ارسال درخواست‌ها به notifyUri آغازگر یا نقطه پایانی API triggers.fire ، از آن برای بازیابی توکن دسترسی جدید استفاده کند.

  • افزونه‌های اسکریپت گوگل اپس : افزونه‌های مبتنی بر اسکریپت گوگل اپس که از تریگرهای زمان‌بندی‌شده (زمان‌محور) برای نظرسنجی رویدادها استفاده می‌کنند، می‌توانند از پیاده‌سازی یک جریان OAuth مستقل صرف‌نظر کنند. از آنجا که تریگرهای زمان‌بندی‌شده مستقیماً در محیط زمان اجرای اسکریپت گوگل اپس اجرا می‌شوند، اسکریپت گوگل اپس به‌طور خودکار توکن‌های OAuth را با استفاده از محدوده‌های اعلام‌شده در مانیفست مدیریت و به‌روزرسانی می‌کند.

تعریف آغازگر در فایل مانیفست

برای تعریف یک آغازگر، آن را به فایل مانیفست افزونه خود ( appsscript.json ) در بلوک addOns.studio.flows.workflowElements اضافه کنید. این پیکربندی هم برای Apps Script و هم برای زمان‌های اجرای HTTP (زمان‌های اجرای جایگزین) ضروری است. عنصر را به عنوان یک workflowTrigger به جای workflowAction (که هنگام تعریف یک مرحله استفاده می‌شود) پیکربندی کنید. برای اطلاعات بیشتر، به ساختار Manifest برای افزونه‌های Google Workspace مراجعه کنید.

درون بلوک workflowTrigger ، موارد زیر را مشخص کنید:

  • inputs : متغیرهایی که کاربر روی کارت پیکربندی پیکربندی می‌کند (مانند نام پروژه، فیلتر منابع و غیره).
  • outputs : متغیرهایی که توسط راه‌انداز به مراحل پایین‌دستی جریان بازگردانده می‌شوند.
  • onConfigFunction : نام تابع فراخوانی که رابط پیکربندی کاربر را نمایش می‌دهد.
  • onManageFunction : نام تابع فراخوانی که توسط گوگل برای مدیریت ایجاد و حذف اشتراک اولیه فراخوانی می‌شود.

نمونه کد زیر یک تعریف مانیفست برای یک شروع کننده رویداد را نشان می‌دهد:

جی‌سون

{
  "timeZone": "America/Los_Angeles",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "addOns": {
    "common": {
      "name": "Trigger App",
      "logoUrl": "https://fonts.gstatic.com/s/i/short-term/release/googlesymbols/start/default/24px.svg",
      "useLocaleFromApp": true
    },
    "studio": {
      "flows": {
        "workflowElements": [
          {
            "id": "triggerDemo",
            "state": "ACTIVE",
            "name": "Event Trigger",
            "description": "Fires when a event occurs in the app.",
            "workflowTrigger": {
              "inputs": [
                {
                  "id": "projectId",
                  "description": "The project identifier to watch.",
                  "cardinality": "SINGLE",
                  "dataType": {
                    "basicType": "STRING"
                  }
                }
              ],
              "outputs": [
                {
                  "id": "eventName",
                  "description": "The name of the triggered event.",
                  "cardinality": "SINGLE",
                  "dataType": {
                    "basicType": "STRING"
                  }
                },
                {
                  "id": "eventMessage",
                  "description": "Detailed event message description.",
                  "cardinality": "SINGLE",
                  "dataType": {
                    "basicType": "STRING"
                  }
                }
              ],
              "onConfigFunction": "onConfigTrigger",
              "onManageFunction": "onManageTrigger"
            }
          }
        ]
      }
    }
  }
}

چرخه عمر اشتراک اولیه را مدیریت کنید

وقتی کاربری جریانی حاوی آغازگر شما را پیکربندی و فعال می‌کند، یا اگر جریان غیرفعال یا حذف شود، گوگل افزونه شما را با استفاده از تابع فراخوانی onManageFunction که در مانیفست اعلام شده است، فراخوانی می‌کند.

شیء رویداد چرخه حیات

تابع فراخوانی یک WorkflowEventObject حاوی زمینه عمل دریافت می‌کند. برای شروع، این شامل موارد زیر است:

  • ایجاد ماشه ( event.workflow.triggerCreation ) : زمانی که جریان منتشر یا فعال می‌شود، فعال می‌شود.

    • triggerId : یک رشته UUID منحصر به فرد که این نمونه ثبت نام آغازگر را مشخص می‌کند.

    • notifyUri : آدرس اینترنتی منحصر به فرد REST API مرتبط با این ثبت نام اولیه (برای مثال، https://workspacestudio.googleapis.com/v1/triggers/YOUR_TRIGGER_ID:fire ).

    • inputs : ورودی‌های متغیری که توسط کاربر از طریق کارت پیکربندی می‌شوند.

  • حذف ماشه ( event.workflow.triggerDeletion ) : زمانی اجرا می‌شود که شروع‌کننده از جریان حذف شود، یا کل جریان غیرفعال یا حذف شود.

    • triggerId : رشته UUID منحصر به فردِ نمونه اشتراکی که قرار است پاکسازی شود.

چرخه عمر اشتراک زمان‌های اجرای جایگزین (HTTP API)

برای افزونه‌هایی که با استفاده از زمان‌های اجرای جایگزین ساخته شده‌اند، اعلان‌های چرخه عمر اشتراک با استفاده از درخواست‌های HTTP POST به URL نقطه پایانی HTTP پیکربندی‌شده افزونه با نام اکشن مشخص‌شده توسط تابع فراخوانی onManageFunction ارسال می‌شوند. محتوای داده با نمایش JSON از WorkflowEventObject مطابقت دارد.

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

پیاده‌سازی کال‌بک‌های چرخه عمر در Apps Script

مثال اسکریپت برنامه‌ها (Apps Script) زیر نحوه پیکربندی کارت رابط کاربری، مدیریت رویدادهای چرخه عمر اشتراک با استفاده از onManageTrigger و ارسال درخواست آغازین به گوگل هنگام وقوع یک رویداد را نشان می‌دهد.

اسکریپت برنامه‌ها

/**
 * Generates and returns the user configuration card to collect inputs.
 */
function onConfigTrigger() {
  const projectInput = CardService.newTextInput()
    .setFieldName("projectId")
    .setTitle("Project ID")
    .setHint("Enter the project identifier to watch");

  const section = CardService.newCardSection()
    .setHeader("Configure Event Trigger")
    .addWidget(projectInput);

  const card = CardService.newCardBuilder()
    .addSection(section)
    .build();

  return card;
}

/**
 * Handles subscription lifecycle events sent from Google Workspace Studio.
 *
 * @param {Object} event The Workspace Studio event object.
 */
function onManageTrigger(event) {
  const triggerCreation = event.workflow.triggerCreation;
  const triggerDeletion = event.workflow.triggerDeletion;

  if (triggerCreation) {
    const triggerId = triggerCreation.triggerId;
    const notifyUri = triggerCreation.notifyUri;
    const inputs = triggerCreation.inputs;

    // Extract input values configured by the user.
    const projectId = inputs["projectId"].stringValues[0];

    // TODO: Save triggerId, notifyUri, and projectId in your database/service.
    // Your backend service listens for events related to 'projectId'
    // and calls notifyUri when those events occur.
    console.log("Trigger subscription created: " + triggerId +
                ", Notify URI: " + notifyUri +
                ", Match Project: " + projectId);

  } else if (triggerDeletion) {
    const triggerId = triggerDeletion.triggerId;

    // TODO: Remove references to triggerId from your database and stop
    // sending future event notifications to the associated notifyUri.
    console.log("Trigger subscription deleted: " + triggerId);
  }
}

/**
 * Mock function showing how your backend service fires the trigger.
 * This logic runs on your service when a watched event occurs.
 *
 * @param {string} notifyUri The stored notifyUri associated with the trigger.
 * @param {string} triggerId The stored triggerId.
 * @param {string} userAccessToken The OAuth 2.0 access token for the user
 *     (obtained using your stored refresh token).
 */
function simulateEventFire(notifyUri, triggerId, userAccessToken) {
  // A unique UUID version 4 is recommended as the requestId for idempotency.
  const requestId = Utilities.getUuid();

  const payload = {
    "name": "triggers/" + triggerId,
    "outputs": {
      "eventName": { "stringValues": ["EventOccurred"] },
      "eventMessage": { "stringValues": ["Hello from the service!"] }
    },
    "requestId": requestId
  };

  const options = {
    "method": "POST",
    "contentType": "application/json",
    "headers": {
      "Authorization": "Bearer " + userAccessToken
    },
    "payload": JSON.stringify(payload),
    "muteHttpExceptions": true
  };

  const response = UrlFetchApp.fetch(notifyUri, options);
  const responseCode = response.getResponseCode();

  if (responseCode === 200) {
    console.log("Trigger successfully fired!");
  } else if (responseCode === 404) {
    // 404 means the trigger registration is invalid or deleted.
    console.log("Trigger not found. Stop sending events for this trigger.");
    // TODO: Clean up the trigger from your backend database.
  } else if (responseCode === 429 || responseCode >= 500) {
    console.log("Temporary error (" + responseCode + "). Retry using exponential backoff.");
  } else {
    console.log("Failed to fire trigger. HTTP Code: " + responseCode + " - " + response.getContentText());
  }
}

استفاده از API استودیو Workspace

شما می‌توانید از رابط برنامه‌نویسی کاربردی (API) Workspace Studio ( workspacestudio.googleapis.com ) برای اطلاع‌رسانی برنامه‌نویسی‌شده به گوگل در مورد رویدادهای آغازین استفاده کنید.

نقاط پایانی در مسیر پایه قرار دارند: https://workspacestudio.googleapis.com/v1 .

یک رویداد آغازین را اطلاع می‌دهد

با استفاده از متد triggers.fire یک آغازگر (starter) برای شروع اجرای یک جریان (flow) راه‌اندازی می‌کند.

  • روش HTTP : POST
  • مسیر : /v1/triggers/{triggerId}:fire (که در آن {triggerId} شناسه منحصر به فردی است که هنگام ایجاد اشتراک تریگر بازیابی می‌شود)
  • دامنه OAuth : https://www.googleapis.com/auth/workspace.studio.trigger

نمونه کد زیر نحوه‌ی اجرای یک starter در درخواست را نشان می‌دهد.

درخواست

{
  "name": "triggers/TRIGGER_ID",
  "outputs": {
    "eventName": {
      "stringValues": [
        "EventOccurred"
      ]
    },
    "eventMessage": {
      "stringValues": [
        "Hello from the service!"
      ]
    }
  },
  "log": {
    "textFormatElements": [
      {
        "text": "An event occurred in the app."
      }
    ]
  },
  "requestId": "UNIQUE_REQUEST_ID"
}
  • name (رشته، الزامی): نام منبعِ شروع‌کننده، که به صورت triggers/{triggerId} قالب‌بندی شده است.
  • outputs (نقشه، اختیاری): نقشه‌ای از متغیرهای خروجی اولیه که داده‌های رویداد را نشان می‌دهند. هر مقدار یک شیء VariableData است که از لیست‌های نوع‌دار (مانند stringValues ، booleanValues ، integerValues ) پشتیبانی می‌کند.
  • log (شیء، اختیاری): یک نمایش نشانه‌گذاری TextFormat که در گزارش‌های فعالیت اجرایی Workspace Studio نشان داده می‌شود.
  • requestId (رشته، اختیاری): یک شناسه منحصر به فرد (UUID نسخه ۴ توصیه می‌شود) با حداکثر ۳۶ کاراکتر ASCII برای اطمینان از یکپارچگی API در تلاش‌های مجدد.

پاسخ

در صورت موفقیت، پاسخ یک شیء JSON خالی {} برمی‌گرداند.

سهمیه‌های API استودیو Workspace

ترافیک ارسالی به سرویس workspacestudio.googleapis.com محدود شده است تا از اضافه بار سیستم جلوگیری شود، استفاده منصفانه از منابع تشویق شود و از عملکرد کلی Google Workspace محافظت شود.

سهمیه‌های زیر اعمال می‌شود:

نوع سهمیه سهمیه
به ازای هر دقیقه برای هر پروژه ۱۰۰۰ درخواست اولیه
به ازای هر دقیقه برای هر کاربر ۱۰۰ درخواست اولیه

انواع سهمیه عبارتند از:

  • به ازای هر دقیقه به ازای هر پروژه : تعداد تجمعی رویدادهای آغازگر که از پروژه گوگل کلود یک توسعه‌دهنده اجرا می‌شوند را به ۱۰۰۰ درخواست در دقیقه برای تمام کاربرانی که آغازگرهای آن را اجرا می‌کنند، محدود می‌کند.
  • به ازای هر دقیقه به ازای هر کاربر : تعداد کل درخواست‌های اولیه‌ی هر کاربر نهایی در یک پروژه ابری مشخص را به ۱۰۰ درخواست در دقیقه محدود می‌کند.

خطاهای سهمیه‌بندی مبتنی بر زمان را مدیریت کنید

اگر از این سهمیه‌ها تجاوز کنید، API کد خطای HTTP 429 Too Many Requests (یا 429 Resource Exhausted ) را برمی‌گرداند که نشان می‌دهد سهمیه نرخ از حد مجاز فراتر رفته است.

برای رفع این خطاها، کد شما باید استثنا را دریافت کرده و از یک استراتژی بازگشت نمایی کوتاه‌شده استفاده کند. بازگشت نمایی، درخواست‌های ناموفق را با استفاده از تأخیرهای تدریجی طولانی‌تر بین تلاش‌ها، از جمله لرزش تصادفی (محاسبه مجدد تأخیر تصادفی در هر تکرار) دوباره امتحان می‌کند تا از همگام‌سازی و تلاش مجدد چندین کلاینت به طور همزمان جلوگیری کند:

  1. یک درخواست به API مربوط به Workspace Studio ارسال کنید.
  2. اگر درخواست با خطای 429 با شکست مواجه شد، 1 second + random_number_milliseconds صبر کنید و دوباره امتحان کنید.
  3. اگر دوباره ناموفق بود، 2 seconds + random_number_milliseconds صبر کنید و دوباره امتحان کنید.
  4. اگر دوباره ناموفق بود، 4 seconds + random_number_milliseconds صبر کنید و دوباره امتحان کنید.
  5. این حلقه را ادامه دهید و تأخیر را تا آستانه‌ی maximum_backoff (معمولاً ۳۲ یا ۶۴ ثانیه) دو برابر کنید.
  6. زمانی که به حداکثر مدت زمان backoff رسیدید، با استفاده از آن تأخیر ثابت دوباره تلاش کنید تا به حداکثر محدودیت تلاش مجدد برسید، سپس متوقف شوید و خطا را ثبت کنید.

بهترین شیوه‌ها

هنگام طراحی و اجرای یک استارت، بهترین شیوه‌های زیر را در نظر بگیرید:

انتشار رویدادهای تکی به جای لیست‌های دسته‌ای

برنامه‌ی آغازین خود را طوری طراحی کنید که برای هر رخداد مجزا (مانند به‌روزرسانی یک رکورد، ارسال یک پیام جدید یا اختصاص یک وظیفه) یک رویداد مجزا منتشر کند، نه اینکه یک رویداد واحد حاوی یک دسته یا فهرست از موارد را منتشر کند:

  • سازگاری با شروع‌کننده‌های داخلی : در Workspace Studio، شروع‌کننده‌های داخلی Google Workspace (مانند دریافت ایمیل در Gmail یا پیوستن کاربر به یک فضا در Google Chat) با یک رویداد واحد فعال می‌شوند. انتشار رویدادهای تک موردی با این رفتار همسو است و یک تجربه سازگار و قابل پیش‌بینی را برای کاربران در تمام شروع‌کننده‌ها فراهم می‌کند.
  • پیکربندی جریان ساده‌تر : مراحل پایین‌دستی در یک جریان معمولاً یک آیتم را در یک زمان پردازش می‌کنند. انتشار رویدادهای تک‌موردی به کاربران اجازه می‌دهد متغیرها را مستقیماً و بدون اضافه کردن مراحل پیچیده برای تکرار روی آرایه‌ها یا تجزیه لیست‌ها، نگاشت کنند.
  • مدیریت جداگانه‌ی تغییرات نظرسنجی و دسته‌ای : اگر سرویس بک‌اند شما از یک API خارجی نظرسنجی می‌کند و چندین مورد تغییر یافته را در یک بازه زمانی نظرسنجی تشخیص می‌دهد، به جای اینکه آنها را در یک رویداد دسته‌ای دسته‌بندی کنید، برای هر مورد یک رویداد آغازین جداگانه راه‌اندازی کنید.
  • مدیریت نرخ و سهمیه رویدادها : از آنجا که اجرای رویدادهای جداگانه برای چندین مورد تغییر یافته می‌تواند باعث ایجاد موجی ناگهانی از درخواست‌ها شود، اطمینان حاصل کنید که سرویس شما در سهمیه API Workspace Studio (مانند محدودیت ۱۰۰ درخواست در دقیقه برای هر کاربر) باقی می‌ماند. اگر یک چرخه نمونه‌برداری حجم زیادی از موارد را به همراه داشته باشد (به عنوان مثال، بیش از ۱۰۰ رکورد تغییر یافته)، ارسال رویدادها را به مرور زمان سرعت بخشیده یا کاهش دهید تا از خطاهای 429 Too Many Requests جلوگیری شود.

رفتارهای اصلی و موارد حاشیه‌ای

هنگام ادغام استارت‌آپ‌ها، توسعه‌دهندگان باید رفتارهای خطای خاص و ویژگی‌های زمان اجرا را مدیریت کنند:

  • عدم پشتیبانی از اجرای آزمایشی : Workspace Studio برای مبتدیان از اجرای آزمایشی پشتیبانی نمی‌کند.
  • قابلیت خودتوانی و جلوگیری از تکرار : اگرچه اکیداً الزامی نیست، اما باید یک requestId منحصر به فرد (مانند UUID) را در HTTP یا Apps Script payload خود قرار دهید. ارائه requestId با اجازه دادن به API برای شناسایی و نادیده گرفتن اعلان‌های تکراری، قابلیت خودتوانی را تضمین می‌کند و از اجرای چندین باره جریان برای یک رویداد واحد جلوگیری می‌کند.
  • جریان‌های غیرفعال و دوباره فعال‌شده : وقتی جریانی که شامل آغازگر شما است در Workspace Studio غیرفعال می‌شود، گوگل یک رویداد چرخه عمر triggerDeletion به فراخوانی onManageFunction شما ارسال می‌کند. علاوه بر این، هرگونه فراخوانی به متد FireTrigger مرتبط، کد خطای 404 Not Found ( Requested entity was not found. ) را برمی‌گرداند. سرویس شما باید با متوقف کردن ارسال اعلان‌های رویداد در آینده برای آن شناسه نمونه آغازگر، به خطاهای 404 واکنش نشان دهد.

    اگر کاربری بعداً جریان را دوباره فعال کند، گوگل با فراخوانی تابع onManageFunction شما با یک رویداد triggerCreation جدید حاوی triggerId و notifyUri جدید، یک چرخه حیات اشتراک جدید را آغاز می‌کند. triggerId قبلی به طور دائم از کار می‌افتد و دوباره فعال نمی‌شود، بنابراین سرویس شما نباید نظرسنجی کند یا بررسی کند که آیا یک نمونه trigger قدیمی دوباره فعال شده است یا خیر. برای اطلاعات بیشتر، به Handle the starter subscription lifecycle مراجعه کنید.

  • حذف اشتراک خودتوان : تابع فراخوانی onManageFunction شما باید درخواست‌های حذف آغازگر از گوگل را به صورت خودتوان مدیریت کند. اگر گوگل چندین بار قلاب حذف را برای یک triggerId یکسان فراخوانی کند (برای مثال، در طول تلاش‌های مجدد به دلیل قطع موقت اتصال)، تابع باید با موفقیت بازگردد.

  • سهمیه‌بندی جریان : فراتر از سهمیه‌بندی‌های API Workspace Studio، جریان‌های کاربری مشمول کنترل‌های سهمیه‌بندی داخلی اضافی هستند. حلقه‌های با فرکانس بالا یا حجم بیش از حد رویداد ممکن است از آستانه‌های ایمنی فراتر روند و منجر به غیرفعال شدن خودکار جریان شوند.