۱. مقدمه
در این آزمایشگاه کد، شما یک پورتال پشتیبانی سریع تعاملی خواهید ساخت که مستقیماً با Google Workspace Studio در ارتباط است. شما یاد خواهید گرفت که چگونه یک گام آغازین سفارشی و یک گام عملی سفارشی بسازید که بتوان آن را فوراً و بدون تکیه بر هیچ زیرساخت شخص ثالثی آزمایش کرد.
ما از اسکریپت Google Apps برای ایجاد موارد زیر استفاده خواهیم کرد:
- یک برنامه وب با فرمی زیبا برای کاربران تا بتوانند به صورت دستی درخواستهای پشتیبانی ارسال کنند.
- یک شروعکننده سفارشی که آن ارسالهای برنامه وب را ضبط میکند و جریان استودیوی فضای کاری را آغاز میکند.
- یک مرحله سفارشی که توضیحات تیکت ورودی را برای شناسایی سطوح فوریت ("زیاد" یا "عادی") تجزیه و تحلیل میکند.
آنچه یاد خواهید گرفت
- نحوه پیکربندی آغازگرها و مراحل در مانیفست
appsscript.jsonشما. - نحوه ساخت
notifyUriدر طول چرخه حیات ثبت نام اولیه. - چگونه میتوان با استفاده از
UrlFetchApp، جریان Workspace Studio را از طریق کد خارجی به صورت برنامهنویسی شده فعال کرد؟ - نحوه ساخت متغیرهای خروجی در مراحل سفارشی شما برای ارسال دادهها به پاییندست.
پیشنیازها
- یک حساب Google Workspace که Google Workspace Studio در آن فعال باشد.
- تنظیم «اجازه دادن به مراحل سفارشی منتشر نشده (آزمایشی)» در کنسول مدیریت دامنه شما (در مسیر برنامهها > Google Workspace > Workspace Studio > تنظیمات مراحل سفارشی ) فعال شده است.
- آشنایی با اسکریپتهای گوگل اپس
۲. راهاندازی پروژه اسکریپت برنامهها
ابتدا، یک پروژه جدید Apps Script برای قرار دادن کد خود ایجاد میکنیم:
- به script.google.com بروید و روی «پروژه جدید» کلیک کنید.
- نام پروژه را «پورتال سریع پشتیبانی» بگذارید.
- کلیک
تنظیمات پروژه در نوار کناری سمت چپ.
- کادر نمایش فایل مانیفست appsscript.json در ویرایشگر را علامت بزنید.
- بازگشت به
نمای ویرایشگر .
یک پروژه استاندارد Google Cloud را پیوند دهید
به طور پیشفرض، پروژههای Apps Script با یک پروژه پنهان و پیشفرض Google Cloud مرتبط هستند. برای فراخوانی API Google Workspace Studio و جلوگیری از خطاهای PERMISSION_DENIED ، باید اسکریپت خود را به یک پروژه Cloud استاندارد تغییر دهید، API را فعال کنید و Google Auth Platform را به درستی پیکربندی کنید.
- انتخاب یا ایجاد یک پروژه: به کنسول گوگل کلود بروید و از منوی کشویی پروژه در بالای صفحه برای انتخاب یک پروژه موجود یا ایجاد یک پروژه جدید استفاده کنید.
- فعال کردن API: پس از فعال شدن پروژه انتخابی شما در نوار بالا، API Enablement Flow را باز کنید و روی Next کلیک کنید و برای Workspace Studio API آن را فعال کنید .
- پیکربندی برندسازی OAuth: صفحه برندسازی پلتفرم Google Auth را باز کنید.
- در صورت درخواست، روی شروع به کار کلیک کنید. (اگر قبلاً پیکربندی شده است، به مرحله ۴ بروید).
- در قسمت اطلاعات برنامه ، نام برنامه و ایمیل پشتیبانی کاربر را وارد کنید. روی بعدی کلیک کنید.
- در قسمت مخاطبان ، گزینه داخلی (یا خارجی در صورت عدم وجود داخلی) را انتخاب کرده و روی بعدی (Next ) کلیک کنید.
- اطلاعات تماس را ارائه دهید، با سیاست داده موافقت کنید و روی ایجاد کلیک کنید.
- پیکربندی دسترسی به دادهها: صفحه دسترسی به دادهها را باز کنید و روی افزودن یا حذف محدودهها کلیک کنید.
- در قسمت «افزودن دستی محدودهها» ، آدرس
https://www.googleapis.com/auth/workspace.studio.triggerرا وارد کنید. - روی «افزودن به جدول» کلیک کنید، سپس «بهروزرسانی» را انتخاب کنید و در نهایت روی «ذخیره» در پایین صفحه کلیک کنید.
- در قسمت «افزودن دستی محدودهها» ، آدرس
- به IAM & Admin > Settings (یا داشبورد Cloud Console) بروید و شماره پروژه را کپی کنید.
- به پروژه Apps Script خود برگردید و کلیک کنید
تنظیمات پروژه در نوار کناری سمت چپ.
- در بخش پروژه پلتفرم ابری گوگل (GCP) ، روی تغییر پروژه کلیک کنید.
- شماره پروژه GCP که کپی کردهاید را وارد کنید و روی تنظیم پروژه کلیک کنید.
پیکربندی مانیفست
فایل appsscript.json که به تازگی قابل مشاهده است را باز کنید. محتویات آن را با کد زیر جایگزین کنید. این مانیفست به صراحت دامنههای OAuth مورد نیاز ما را فهرست میکند و شروعکننده ما را به عنوان workflowTrigger و اکشن را به عنوان workflowAction در زیر بلوک studio.flows.workflowElements تعریف میکند.
{
"timeZone": "America/Los_Angeles",
"exceptionLogging": "STACKDRIVER",
"runtimeVersion": "V8",
"webapp": {
"executeAs": "USER_ACCESSING",
"access": "MYSELF"
},
"oauthScopes": [
"https://www.googleapis.com/auth/script.external_request",
"https://www.googleapis.com/auth/workspace.studio.trigger",
"https://www.googleapis.com/auth/script.storage",
"https://www.googleapis.com/auth/script.locale"
],
"urlFetchWhitelist": [
"https://workspacestudio.googleapis.com/"
],
"addOns": {
"common": {
"name": "Support Extension",
"logoUrl": "https://www.gstatic.com/images/branding/productlogos/buganizer/v1/192px.svg",
"useLocaleFromApp": true
},
"studio": {
"flows": {
"workflowElements": [
{
"id": "supportTicketTrigger",
"state": "ACTIVE",
"name": "New Support Ticket",
"description": "Fires when someone submits a ticket via the Web App.",
"workflowTrigger": {
"inputs": [],
"outputs": [
{
"id": "ticketTitle",
"description": "The title of the ticket",
"cardinality": "SINGLE",
"dataType": { "basicType": "STRING" }
},
{
"id": "ticketDescription",
"description": "The full description of the issue",
"cardinality": "SINGLE",
"dataType": { "basicType": "STRING" }
}
],
"onConfigFunction": "onConfigTrigger",
"onManageFunction": "onManageTrigger"
}
},
{
"id": "urgencyDetectorStep",
"state": "ACTIVE",
"name": "Detect Urgency",
"description": "Scans the ticket description to detect High or Normal urgency.",
"workflowAction": {
"inputs": [
{
"id": "ticketDescription",
"description": "The ticket description",
"cardinality": "SINGLE",
"dataType": { "basicType": "STRING" }
}
],
"outputs": [
{
"id": "urgencyLevel",
"description": "The urgency High/Normal",
"cardinality": "SINGLE",
"dataType": { "basicType": "STRING" }
}
],
"onConfigFunction": "onConfigUrgency",
"onExecuteFunction": "onExecuteUrgency"
}
}
]
}
}
}
}
۳. رابط کاربری برنامه وب را بسازید
برای ارائه یک روش بصری و قابل آزمایش برای راهاندازی برنامهی آغازین بدون استفاده از ابزارهای ترمینال یا وبهوکهای شخص ثالث، یک برنامهی وب Apps Script خواهیم ساخت.
در ویرایشگر اسکریپت برنامهها، کنار فایلها ، کلیک کنید یک فایل اضافه کنید و HTML را انتخاب کنید. نام آن را
index.html بگذارید (پسوند .html به طور خودکار اضافه میشود).
کد رابط کاربری سادهشدهی زیر را جایگذاری کنید:
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
body { font-family: Arial, sans-serif; padding: 20px; max-width: 500px; margin: auto; }
label { font-weight: bold; display: block; margin-top: 15px; }
input, textarea { width: 100%; margin-top: 5px; padding: 10px; box-sizing: border-box; }
button { background-color: #1a73e8; color: white; border: none; padding: 10px 15px; margin-top: 15px; font-weight: bold; cursor: pointer; border-radius: 4px; }
button:hover { background-color: #1557b0; }
#status { margin-top: 15px; color: green; font-weight: bold; }
</style>
</head>
<body>
<h2>Support Quick Portal</h2>
<p>Submit your issue below to trigger the Workspace Studio flow.</p>
<label for="title">Ticket Title</label>
<input type="text" id="title" placeholder="e.g. Broken monitor">
<label for="description">Issue Description</label>
<textarea id="description" rows="4" placeholder="Explain your issue (use words like 'urgent' to test the step!)..."></textarea>
<button onclick="submitTicket()">Submit Ticket</button>
<div id="status"></div>
<script>
function submitTicket() {
const title = document.getElementById('title').value;
const description = document.getElementById('description').value;
const statusEl = document.getElementById('status');
if (!title || !description) {
statusEl.style.color = "red";
statusEl.innerText = "Please fill out both fields.";
return;
}
statusEl.style.color = "green";
statusEl.innerText = "Submitting ticket...";
google.script.run
.withSuccessHandler(function(response) {
statusEl.innerText = response;
})
.withFailureHandler(function(error) {
statusEl.style.color = 'red';
statusEl.innerText = 'Error: ' + error.message;
})
.submitTicketToStudio(title, description);
}
</script>
</body>
</html>
۴. اسکریپتهای بکاند را بسازید
حالا بیایید همه چیز را به هم وصل کنیم. برای اینکه کد خوانا بماند، منطق برنامه وب، منطق شروعکننده و منطق مرحله اقدام را در سه فایل اسکریپت مختلف جدا میکنیم.
WebApp.gs
فایل پیشفرض Code.gs را در ویرایشگر به WebApp.gs تغییر نام دهید، کد تکراری myFunction را حذف کنید و بلوک زیر را در آن کپی و جایگذاری کنید. این فایل، میزبانی وب اپلیکیشن را مدیریت میکند:
/** --- WEB APP HOSTING --- **/
/**
* Serves the HTML UI when users visit the web app URL.
*/
function doGet() {
return HtmlService.createHtmlOutputFromFile('index')
.setTitle('Support Quick Portal')
.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);
}
/**
* Called by the Web App form. It calls the Workspace Studio API.
*/
function submitTicketToStudio(title, description) {
const props = PropertiesService.getUserProperties();
const notifyUri = props.getProperty('notifyUri');
const triggerId = props.getProperty('triggerId');
if (!notifyUri || !triggerId) {
throw new Error('Trigger URL missing! Make sure the flow is enabled in Workspace Studio.');
}
// Use ScriptApp.getOAuthToken() (requires the workspace.studio.trigger scope in manifest)
const token = ScriptApp.getOAuthToken();
const requestId = Utilities.getUuid();
// Package our outputs mapped in appsscript.json
const payload = {
"name": "triggers/" + triggerId,
"outputs": {
"ticketTitle": { "stringValues": [title] },
"ticketDescription": { "stringValues": [description] }
},
"requestId": requestId
};
const options = {
"method": "POST",
"contentType": "application/json",
"headers": { "Authorization": "Bearer " + token },
"payload": JSON.stringify(payload),
"muteHttpExceptions": true
};
// Fire!
const response = UrlFetchApp.fetch(notifyUri, options);
if (response.getResponseCode() !== 200) {
console.error(response.getContentText());
throw new Error('Workspace Studio API Error: ' + response.getResponseCode());
}
return 'Ticket successfully routed to Workspace Studio!';
}
استارتر.gs
سپس، نشانگر ماوس را روی فایلها ببرید و کلیک کنید. یک فایل اضافه کنید ، Script را انتخاب کنید و نام آن را
Starter.gs بگذارید. بلوک زیر را کپی کرده و در آن قرار دهید. این فایل پیکربندی Starter و مدیریت چرخه عمر Workspace Studio را مدیریت میکند:
/** --- STARTER LOGIC --- **/
/**
* Workspace Studio calls this to display the config UI when the user adds the starter.
* We just return a static message since there are no properties to configure.
*/
function onConfigTrigger() {
const section = CardService.newCardSection()
.setHeader("Configure Web App Starter")
.addWidget(CardService.newTextParagraph().setText("Ready to go! Once you enable this flow, deploy your Apps Script project as a Web App to submit tickets."));
return CardService.newCardBuilder().addSection(section).build();
}
/**
* Workspace Studio posts data here to manage the lifecycle (enable/disable the trigger).
* Critically, we must construct or save the `notifyUri` and `triggerId` to call it later.
*/
function onManageTrigger(event) {
const triggerCreation = event.workflow.triggerCreation;
const triggerDeletion = event.workflow.triggerDeletion;
const props = PropertiesService.getUserProperties();
if (triggerCreation) {
// Save the unique URL and ID when the flow is enabled
// Note: notifyUri might be omitted, so fallback to constructing it dynamically
const notifyUri = triggerCreation.notifyUri || `https://workspacestudio.googleapis.com/v1/triggers/${triggerCreation.triggerId}:fire`;
props.setProperty('notifyUri', notifyUri);
props.setProperty('triggerId', triggerCreation.triggerId);
} else if (triggerDeletion) {
// Cleanup if the user deletes the flow
props.deleteProperty('notifyUri');
props.deleteProperty('triggerId');
}
}
اکشن.gs
سپس، نشانگر ماوس را روی فایلها ببرید و کلیک کنید. یک فایل اضافه کنید ، Script را انتخاب کنید و نام آن را
Action.gs بگذارید. منطق مرحله فوریت زیر را کپی و در آن جایگذاری کنید:
/** --- ACTION STEP LOGIC --- **/
/**
* Workspace Studio configuration card for the Step.
* We prompt the user to bind a variable to our "ticketDescription" input.
*/
function onConfigUrgency() {
const input = CardService.newTextInput()
.setFieldName("ticketDescription")
.setTitle("Source Description")
.setHint('Select the description variable outputted by the starter')
.setHostAppDataSource(
CardService.newHostAppDataSource().setWorkflowDataSource(CardService.newWorkflowDataSource().setIncludeVariables(true))
);
const section = CardService.newCardSection()
.setHeader("Urgency Detector Step")
.addWidget(input);
return CardService.newCardBuilder().addSection(section).build();
}
/**
* The synchronous logic executed during the Step.
*/
function onExecuteUrgency(event) {
// Read mapped inputs
let description = event.workflow.actionInvocation.inputs["ticketDescription"].stringValues[0];
if (!description) description = "";
const urgentKeywords = ['urgent', 'crash', 'broken', 'down', 'fire'];
let urgencyLevel = 'Normal';
if (urgentKeywords.some(keyword => description.toLowerCase().includes(keyword))) {
urgencyLevel = 'High';
}
// Package outputs correctly
const variableDataMap = {
"urgencyLevel": AddOnsResponseService.newVariableData().addStringValue(urgencyLevel)
};
return outputVariables(variableDataMap);
}
/**
* Helper strictly enforcing the expected Step object return type.
*/
function outputVariables(variableDataMap) {
const workflowAction = AddOnsResponseService.newReturnOutputVariablesAction()
.setVariableDataMap(variableDataMap);
const hostAppAction = AddOnsResponseService.newHostAppAction()
.setWorkflowAction(workflowAction);
return AddOnsResponseService.newRenderActionBuilder()
.setHostAppAction(hostAppAction)
.build();
}
۵. استقرار و آزمایش
حالا که کدها نوشته شدهاند، بیایید پروژه را مستقر و پیکربندی کنیم.
مرحله ۱: اسکریپت را دوباره مجاز کنید
از آنجا که شما یک پروژه استاندارد جدید Google Cloud را لینک کردهاید، باید صریحاً دامنههای اسکریپت (مانند script.external_request که توسط UrlFetchApp استفاده میشود) را برای پروژه جدید مجاز کنید.
- در ویرایشگر Apps Script، در قسمت Files ، گزینه
WebApp.gsرا انتخاب کنید، سپس از منوی کشویی نوار ابزار بالا، تابعdoGetرا انتخاب کنید. - روی اجرا کلیک کنید.
- پیامی با عنوان «نیاز به مجوز» ظاهر میشود. روی «بررسی مجوزها » کلیک کنید.
- حساب کاربری خود را انتخاب کنید و اسکریپت را تأیید کنید. اگر هشدار «برنامه تأیید نشده» را مشاهده کردید، برای دور زدن، روی پیشرفته -> رفتن به پورتال سریع پشتیبانی کلیک کنید.
- منتظر بمانید تا گزارش اجرا، عبارت «اجرا تکمیل شد» را نشان دهد، که تأیید میکند اسکریپت اکنون بهطور کامل مجاز شده است.
مرحله ۲: افزونه و برنامه وب را آزمایش کنید
از آنجایی که appsscript.json شما هم یک افزونه و هم یک برنامه وب را تعریف میکند، میتوانید هر دو را همزمان پیکربندی کنید.
- در گوشه بالا سمت راست Apps Script، روی Deploy > Test deployments کلیک کنید.
- در کنار انتخاب نوع ، کلیک کنید
انواع استقرار را فعال کنید و مطمئن شوید که افزونههای Google Workspace تیک خوردهاند، سپس روی نصب کلیک کنید.
- کلیک
دوباره انواع استقرار را فعال کنید ، مطمئن شوید که برنامه وب تیک خورده است و URL را کپی کنید (به
/devختم میشود). این URL مربوط به برنامه وب Support Quick Portal است که ساختهاید. - روی «انجام شد» کلیک کنید. ممکن است لازم باشد مرورگر خود را قبل از اینکه Workspace Studio افزونه را ثبت کند، رفرش کنید.
مرحله ۳: پیکربندی Studio Flow
- Google Workspace Studio را از طریق studio.workspace.google.com باز کنید.
- کلیک
ابزار Add را در سمت چپ اضافه کنید و Flow را انتخاب کنید.
- برای پیکربندی افزونهی شروعکننده، روی «انتخاب یک شروعکننده» کلیک کنید، سپس افزونهی پشتیبانی نصبشدهی خود را انتخاب کنید > تیکت پشتیبانی جدید . اگر با پیام «نیاز به مجوز» مواجه شدید، روی «اعطای مجوز» کلیک کنید تا افزونه بتواند به دادههای شما دسترسی پیدا کند.
- سپس، در بخش اقدامات (Actions)، روی «انتخاب یک مرحله» (Choose a step) کلیک کنید، به «پشتیبانی از افزونه» (Support Extension) بروید و مرحله «تشخیص فوریت» (Detecting Urgency) را انتخاب کنید.
- در توضیحات منبع ، کلیک کنید
متغیرها را انتخاب کنید و مرحله ۱: درخواست پشتیبانی جدید > شرح کامل مشکل (
ticketDescription) را انتخاب کنید. - دوباره روی «انتخاب یک مرحله» کلیک کنید و یک مرحله از پیش تعریف شده مانند Gmail > Send an email یا Chat > Notify me in Chat را انتخاب کنید.
- اگر جیمیل را انتخاب کردید:
- به: ایمیل خودتان را قرار دهید.
- موضوع: بلیط
ticketTitleاولویتurgencyLevelاست - پیام:
ticketDescription
- اگر چت را انتخاب کردید:
- پیام: اولویت
ticketTitleurgencyLevelاست.ticketDescription
- پیام: اولویت
- اگر جیمیل را انتخاب کردید:
- گردش کار را روشن کنید . اگر از شما خواسته شد که نام گردش خود را تغییر دهید ، نامی مانند
Support Ticket Routerوارد کنید و ذخیره کنید. این کار چرخه حیاتonManageTriggerرا فعال میکند وnotifyUriرا ذخیره میکند.
مرحله ۴: اجرای شبیهسازی
- آدرس اینترنتی برنامه وب را که قبلاً در مرحله 2 این صفحه کپی کردهاید، در یک برگه مرورگر جدید باز کنید (به /dev ختم میشود).
- فرم را پر کنید. مطمئن شوید که یک کلمه کلیدی محرک (مانند "فوری" یا "خرابی") را در توضیحات وارد میکنید.
- روی ارسال کلیک کنید. منتظر پیام «بلیط با موفقیت مسیریابی شد» باشید.
- گزارش فعالیت Workspace Studio، صندوق ورودی Gmail یا Google Chat خود را (بسته به عملی که انتخاب کردهاید) بررسی کنید. باید یک پیام یا ایمیل با برچسب فوریت "زیاد" که به صورت بومی با استفاده از عناصر اسکریپت برنامههای سفارشی شما یکپارچه شده است، مشاهده کنید.
۶. تمیز کردن
برای جلوگیری از شلوغی فضای کاری و حساب Google Cloud خود، میتوانید منابعی را که در طول این آزمایش کد ایجاد کردهاید، پاک کنید.
- جریان استودیوی فضای کاری را حذف کنید:
- studio.workspace.google.com را باز کنید.
- جریان
Support Ticket Routerخود را پیدا کنید. - روی منوی سه نقطه کنار آن کلیک کنید و گزینه Delete را انتخاب کنید.
- پروژه اسکریپت برنامهها را حذف کنید:
- به script.google.com بروید.
- پروژه
Support Quick Portalرا پیدا کنید. - روی منوی سه نقطه کلیک کنید و گزینه حذف را انتخاب کنید.
- پروژه ابری گوگل را متوقف کنید:
- به کنسول ابری گوگل بروید.
- مطمئن شوید که پروژه جدید شما در منوی کشویی بالا انتخاب شده است.
- به بخش مدیریت و دسترسی > تنظیمات بروید و روی خاموش کردن کلیک کنید.
۷. نتیجهگیری
شما با موفقیت یک اکوسیستم کامل برای افزونههای سفارشی Google Workspace Studio بدون تکیه بر هیچ اشتراک شخص ثالث خارجی ایجاد کردهاید.
آنچه ما پوشش دادیم:
- استفاده از
workflowTriggerدر کنارonManageFunctionبرای ثبت و مدیریت صحیح رویدادهای چرخه عمر گوگل. - احراز هویت درخواستهای backend با استفاده از
ScriptApp.getOAuthToken()در برابر نقاط پایانی API مربوط بهworkspacestudio.googleapis.com. - استفاده از
workflowActionبرای پردازش همزمان متغیرهای ورودی و تولید خروجیهای بعدی.
اکنون میتوانید با تغییر محل شروع برنامه وب (یا وبهوک ورودی) خود، این اصول را برای اتصال به پلتفرمهای واقعی SaaS مانند Jira، Salesforce یا Zendesk مقیاسبندی کنید.