1. परिचय
Google Workspace Studio की मदद से, Gmail, Google Chat, Google Drive, और Google Sheets जैसे Google Workspace ऐप्लिकेशन में कारोबार से जुड़ी प्रोसेस को ऑटोमेट किया जा सकता है. जब आपके वर्कफ़्लो को किसी बाहरी वेब ऐप्लिकेशन से शुरू करने या अपने क्लाउड एनवायरमेंट में कस्टम लॉजिक चलाने की ज़रूरत हो, तब Cloud Run पर Node.js में, एचटीटीपी Google Workspace ऐड-ऑन की मदद से Google Workspace Studio को बढ़ाया जा सकता है:
- कस्टम स्टार्टर चरण (
workflowTrigger): यह Google Workspace Studiotriggers.fireREST API को कॉल करके, बाहरी इवेंट होने पर Google Workspace Studio फ़्लो शुरू करता है. जैसे, ग्राहक के किसी इंटरनल वेब पोर्टल में टिकट सबमिट करने पर. - कस्टम ऐक्शन स्टेप (
workflowAction): यह फ़्लो में पहले के चरणों से वैरिएबल लेता है, आपकी Node.js सेवा में कस्टम लॉजिक या एआई इन्फ़रेंस चलाता है, और आउटपुट वैरिएबल को Google Workspace Studio पर वापस भेजता है.
इस कोडलैब में, Google Workspace Studio के लिए एक पूरा Node.js एचटीटीपी एक्सटेंशन बनाया और उसे Cloud Run पर डिप्लॉय किया जाता है. साथ ही, Cloud Firestore का इस्तेमाल करके, कंटेनर के अलग-अलग वर्शन में चालू फ़्लो ट्रिगर करने वाली सदस्यताओं और सबमिट किए गए टिकट को सेव किया जाता है. इसके अलावा, Gemini Enterprise Agent Platform पर Gemini 3.8 Flash (gemini-3.8-flash) का इस्तेमाल करके, कस्टम ऐक्शन स्टेप में टिकट की प्राथमिकता तय की जाती है. इसमें कीवर्ड मैचिंग फ़ॉलबैक की सुविधा भी मिलती है.
आपको क्या बनाना है
- Cloud Run पर Node.js, Express, और Firestore की मदद से बनाया गया Support Quick Portal वेब ऐप्लिकेशन और HTTP Google Workspace ऐड-ऑन.
- नया सहायता टिकट कस्टम स्टार्टर चरण (
supportTicketTrigger), जोstudio_triggersFirestore कलेक्शन में चालू फ़्लो की सदस्यताएं बनाए रखता है, सबमिट किए गए टिकटों कोsupport_ticketsFirestore कलेक्शन में लॉग करता है, और वेब पोर्टल में टिकट सबमिट किए जाने पर ट्रिगर होता है. यहticketTitleऔरticketDescriptionको Google Workspace Studio फ़्लो में पास करता है. - Gemini Enterprise के एजेंट प्लैटफ़ॉर्म (
aiplatform.googleapis.com) पर, Gemini 3.8 Flash (gemini-3.8-flash) का इस्तेमाल करके टिकट की प्राथमिकता का पता लगाने वाला प्राथमिकता का पता लगाएं कस्टम ऐक्शन स्टेप (urgencyDetectorStep). इसमें कीवर्ड मैचिंग (urgent,blocker,critical) पर अपने-आप फ़ॉलबैक होने की सुविधा भी है.
आपको क्या सीखने को मिलेगा
workflowTriggerऔरworkflowActionएलिमेंट के साथ, एचटीटीपी Google Workspace ऐड-ऑन डिप्लॉयमेंट मेनिफ़ेस्ट (deployment.json) को कॉन्फ़िगर करने का तरीका.studio_triggersFirestore कलेक्शन में, Google Workspace Studio ट्रिगर की सदस्यताओं (triggerId,notifyUri, औरuserOAuthToken) को कैसे बनाए रखें औरtriggers.fireREST API का इस्तेमाल करके फ़्लो कैसे ट्रिगर करें.- कीवर्ड फ़ॉलबैक के साथ, Gemini Enterprise Agent Platform पर Gemini 3.8 Flash (
gemini-3.8-flash) के स्ट्रक्चर्ड आउटपुट का इस्तेमाल करके, Node.js मेंworkflowActionकस्टम स्टेप बनाने का तरीका.
ज़रूरी शर्तें
- Google Workspace खाता, जिसमें Google Workspace Studio का ऐक्सेस हो.
- बिलिंग की सुविधा वाला Google Cloud प्रोजेक्ट. इसे आपके उपयोगकर्ता खाते के साथ-साथ, उसी Google Workspace संगठन में बनाया गया हो. इससे आपको टेस्टिंग के लिए, पब्लिश नहीं किए गए ऐड-ऑन डिप्लॉयमेंट इंस्टॉल करने में मदद मिलेगी.
2. Google Cloud प्रोजेक्ट और Firestore सेट अप करना
इस चरण में, आपको अपने प्रोजेक्ट के लिए OAuth के लिए सहमति देने की स्क्रीन को कॉन्फ़िगर करना होगा. साथ ही, Cloud Shell में ज़रूरी Google Cloud और Google Workspace API चालू करने होंगे. इसके अलावा, आपको (default) Firestore डेटाबेस को उपलब्ध कराना होगा और ऐड-ऑन के लिए अनुमति देने वाले सेवा खाते को शुरू करना होगा.
- Google Cloud Console खोलें. इसके बाद, अपना Google Cloud प्रोजेक्ट चुनें और सबसे ऊपर मौजूद नेविगेशन बार में, Cloud Shell चालू करें आइकॉन पर क्लिक करें.
- OAuth के लिए सहमति की स्क्रीन को कॉन्फ़िगर करें, ताकि Google Workspace आपके ऐड-ऑन के लिए OAuth क्लाइंट उपलब्ध करा सके:
- Google Auth Platform Branding पेज खोलें.
- अगर कहा जाए, तो शुरू करें पर क्लिक करें. (अगर आपकी सहमति स्क्रीन पहले से कॉन्फ़िगर है, तो तीसरे चरण पर जाएं.)
- ऐप्लिकेशन की जानकारी में जाकर, ऐप्लिकेशन के नाम के लिए
Support Extensionडालें. इसके बाद, उपयोगकर्ता सहायता के लिए ईमेल पता चुनें और आगे बढ़ें पर क्लिक करें. - दर्शक में जाकर, इंटरनल को चुनें. इसके बाद, आगे बढ़ें पर क्लिक करें.
- संपर्क जानकारी में जाकर, अपना ईमेल पता डालें और आगे बढ़ें पर क्लिक करें.
- पूरा करें में जाकर, Google API सेवाओं के उपयोगकर्ता के डेटा से जुड़ी नीति से सहमत हों. इसके बाद, जारी रखें पर क्लिक करें और फिर बनाएं पर क्लिक करें.
- Cloud Shell में, अपना ऐक्टिव प्रोजेक्ट सेट करें. इसके लिए,
YOUR_PROJECT_IDको अपने Google Cloud प्रोजेक्ट आईडी से बदलें. इसके बाद, ज़रूरी एपीआई चालू करें:gcloud config set project YOUR_PROJECT_ID gcloud services enable \ aiplatform.googleapis.com \ firestore.googleapis.com \ run.googleapis.com \ cloudbuild.googleapis.com \ artifactregistry.googleapis.com \ appsmarket-component.googleapis.com \ gsuiteaddons.googleapis.com \ workspacestudio.googleapis.com us-central1में अपना(default)Firestore डेटाबेस उपलब्ध कराएं. अगर यह पहले से मौजूद नहीं है, तो Google Workspace ऐड-ऑन सेवा खाते को शुरू करें:gcloud firestore databases describe --database="(default)" >/dev/null 2>&1 || \ gcloud firestore databases create \ --database="(default)" \ --location=us-central1 \ --type=firestore-native \ --quiet gcloud workspace-add-ons get-authorization
3. Firestore और Gemini 3.8 Flash की मदद से Node.js ऐप्लिकेशन बनाना
इस चरण में, ~/studio-support-addon में Node.js ऐप्लिकेशन बनाया जाता है. कोड को मॉड्यूलर और पढ़ने में आसान बनाने के लिए, प्रोजेक्ट को पांच फ़ोकस की गई फ़ाइलों में व्यवस्थित किया जाता है:
firestore.js: यह Cloud Firestore क्लाइंट (studio_triggersऔरsupport_ticketsकलेक्शन) को शुरू करता है. साथ ही, कैश किए गए OAuth टोकन को रीफ़्रेश करता है.starter.js: यह नया सहायता टिकट कस्टम स्टार्टर स्टेप वेबहुक (/onConfigTriggerऔर/onManageTrigger) लागू करता है.action.js: यह Gemini 3.8 Flash (gemini-3.8-flash) का इस्तेमाल करके, Detect Urgency कस्टम ऐक्शन स्टेप वेबहुक (/onConfigUrgencyऔर/onExecuteUrgency) लागू करता है. इसमें कीवर्ड मैचिंग फ़ॉलबैक का इस्तेमाल किया जाता है.portal.js: यह Support Quick Portal के वेब यूज़र इंटरफ़ेस (GET /) को दिखाता है और Google Workspace Studio के चालू ट्रिगर (POST /api/submit-ticket) को ट्रिगर करता है.index.js: यह सभी Express रास्तों को एक साथ जोड़ता है और एचटीटीपी सर्वर शुरू करता है.
प्रोजेक्ट शुरू करें और package.json
- प्रोजेक्ट डायरेक्ट्री बनाएं और उसमें जाएं:
mkdir -p ~/studio-support-addon && cd ~/studio-support-addon express,@google-cloud/firestore, और@google/genaiकी मदद सेpackage.jsonबनाएँ:cat << 'EOF' > package.json { "name": "studio-support-addon", "version": "1.0.0", "type": "module", "main": "index.js", "scripts": { "start": "node index.js" }, "dependencies": { "@google-cloud/firestore": "^7.11.0", "@google/genai": "^1.0.0", "express": "^4.21.2" } } EOF
firestore.js — शेयर की गई Firestore स्थिति और OAuth टोकन रीफ़्रेश
अपनी दो Firestore कलेक्शन को मैनेज करने और उपयोगकर्ता के OAuth टोकन को कैश मेमोरी में सेव करके रखने के लिए, firestore.js बनाएं:
studio_triggers: यह कुकी, Google Workspace Studio की चालू फ़्लो सदस्यताएं (triggerId,notifyUri, औरuserOAuthToken) सेव करती है, ताकि Cloud Run कंटेनर के रीस्टार्ट होने और स्केल-टू-ज़ीरो इवेंट के बाद भी ये सदस्यताएं बनी रहें.support_tickets: यह कुकी, पोर्टल के ज़रिए सबमिट किए गए हर सहायता टिकट का रिकॉर्ड सेव करती है.refreshTokenInFirestore(req): जब भी Google Workspace Studio आपके किसी वेबहुक एंडपॉइंट को कॉल करता है, तो इसमें कुछ समय के लिए मान्य रहने वालाauthorizationEventObject.userOAuthTokenशामिल होता है. यह हेल्पर, चालू ट्रिगर दस्तावेज़ों को नए टोकन के साथ अपडेट करता है, ताकि बैकग्राउंड मेंtriggers.fireकॉल को अनुमति मिलती रहे.
cat << 'EOF' > firestore.js
import { Firestore } from '@google-cloud/firestore';
export const db = new Firestore({
projectId: process.env.GOOGLE_CLOUD_PROJECT || undefined,
databaseId: '(default)',
ignoreUndefinedProperties: true,
});
export const triggersCollection = db.collection(
process.env.FIRESTORE_TRIGGERS_COLLECTION || 'studio_triggers'
);
export const ticketsCollection = db.collection(
process.env.FIRESTORE_TICKETS_COLLECTION || 'support_tickets'
);
// Keep cached userOAuthToken fresh across active trigger documents
export async function refreshTokenInFirestore(req) {
const freshToken = req.body?.authorizationEventObject?.userOAuthToken;
if (!freshToken) return;
try {
const snapshot = await triggersCollection.get();
if (snapshot.empty) return;
const batch = db.batch();
snapshot.docs.forEach((doc) => {
batch.set(
doc.ref,
{ userOAuthToken: freshToken, updatedAt: new Date().toISOString() },
{ merge: true }
);
});
await batch.commit();
} catch (err) {
console.error('Error refreshing OAuth token in Firestore:', err.message);
}
}
EOF
starter.js — कस्टम स्टार्टर स्टेप (workflowTrigger)
Google Workspace Studio के कस्टम स्टार्टर स्टेप के लिए ज़रूरी दो वेबहुक एंडपॉइंट लागू करने के लिए, starter.js बनाएं:
onConfigTrigger(POST /onConfigTrigger): इस इवेंट को तब कॉल किया जाता है, जब कोई उपयोगकर्ता Google Workspace Studio में नया सहायता टिकट को अपने फ़्लो के स्टार्टर के तौर पर चुनता है. यह फ़ंक्शन, स्टार्टर के बारे में बताने वालाpushCardनेविगेशन ऐक्शन दिखाता है.onManageTrigger(POST /onManageTrigger): इस फ़ंक्शन को तब कॉल किया जाता है, जब कोई उपयोगकर्ता किसी फ़्लो को चालू (req.body.workflow.triggerCreation) करता है या उसे बंद करता है / मिटाता है (req.body.workflow.triggerDeletion). यहstudio_triggersFirestore कलेक्शन में सदस्यता वाले दस्तावेज़ को सेव करता है या मिटाता है.
cat << 'EOF' > starter.js
import { triggersCollection, refreshTokenInFirestore } from './firestore.js';
// Custom Starter Configuration Card
export async function onConfigTrigger(req, res) {
await refreshTokenInFirestore(req);
res.status(200).json({
action: {
navigations: [
{
pushCard: {
sections: [
{
header: 'Support Ticket Listener',
widgets: [
{
textParagraph: {
text: 'This starter listens for new tickets submitted through the Support Quick Portal and stores subscriptions in Firestore.',
},
},
],
},
],
},
},
],
},
});
}
// Custom Starter Subscription Lifecycle (Firestore studio_triggers collection)
export async function onManageTrigger(req, res) {
try {
const triggerCreation = req.body?.workflow?.triggerCreation;
const triggerDeletion = req.body?.workflow?.triggerDeletion;
const userOAuthToken =
req.body?.authorizationEventObject?.userOAuthToken || null;
if (triggerCreation?.triggerId) {
const triggerId = String(triggerCreation.triggerId);
const docId = encodeURIComponent(triggerId);
await triggersCollection.doc(docId).set(
{
triggerId,
notifyUri: triggerCreation.notifyUri || null,
...(userOAuthToken ? { userOAuthToken } : {}),
updatedAt: new Date().toISOString(),
},
{ merge: true }
);
}
if (triggerDeletion?.triggerId) {
const triggerId = String(triggerDeletion.triggerId);
const docId = encodeURIComponent(triggerId);
await triggersCollection.doc(docId).delete();
}
if (!triggerCreation && !triggerDeletion && userOAuthToken) {
await refreshTokenInFirestore(req);
}
} catch (err) {
console.error('Error in /onManageTrigger:', err.message);
}
res.status(200).json({});
}
EOF
action.js — Gemini 3.8 Flash की मदद से कस्टम ऐक्शन स्टेप (workflowAction)
Google Workspace Studio की कस्टम ऐक्शन सुविधा के लिए ज़रूरी दो वेबहुक एंडपॉइंट लागू करने के लिए, action.js बनाएं:
onConfigUrgency(POST /onConfigUrgency): यहtextInputविजेट वाला कॉन्फ़िगरेशन कार्ड दिखाता है. यहhostAppDataSource.workflowDataSource.includeVariables: trueसेट करता है, ताकि उपयोगकर्ता स्टार्टर चरण से मिलेticketDescriptionवैरिएबल को चुन सकें.onExecuteUrgency(POST /onExecuteUrgency): यहreq.body.workflow.actionInvocation.inputsसे मिलेticketDescriptionइनपुट को पढ़ता है. इसके बाद, Gemini 3.8 Flash (gemini-3.8-flash) का इस्तेमाल करके, Gemini Enterprise Agent Platform पर, कारोबार पर पड़ने वाले असर और ज़रूरी होने के हिसाब से इनपुट को कैटगरी में बांटता है. साथ ही, स्ट्रक्चर्ड आउटपुट (responseSchemaenum["High", "Normal"]) देता है. अगर मॉडल कॉल फ़ेल हो जाता है, तो यहdetectKeywordUrgency()(urgent,blocker,critical) पर वापस आ जाता है. इसके बाद,hostAppAction.workflowAction.returnOutputVariablesActionका इस्तेमाल करके,urgencyLevelआउटपुट वैरिएबल दिखाता है.
cat << 'EOF' > action.js
import { GoogleGenAI, Type } from '@google/genai';
import { refreshTokenInFirestore } from './firestore.js';
// Initialize Google GenAI SDK for the Gemini Enterprise Agent Platform
const ai = new GoogleGenAI({
vertexai: true,
project: process.env.GOOGLE_CLOUD_PROJECT,
location: 'global',
});
// Fallback keyword classifier if the Gemini API call is unavailable
export function detectKeywordUrgency(description) {
const lower = (description || '').toLowerCase();
return lower.includes('urgent') ||
lower.includes('blocker') ||
lower.includes('critical')
? 'High'
: 'Normal';
}
// Custom Action Step Configuration Card
export async function onConfigUrgency(req, res) {
await refreshTokenInFirestore(req);
res.status(200).json({
action: {
navigations: [
{
pushCard: {
sections: [
{
header: 'Urgency Detector Step',
widgets: [
{
textInput: {
name: 'ticketDescription',
label: 'Source Description',
hintText:
'Select the description variable outputted by the starter',
hostAppDataSource: {
workflowDataSource: {
includeVariables: true,
},
},
},
},
],
},
],
},
},
],
},
});
}
// Custom Action Step Execution: Gemini 3.8 Flash with keyword fallback
export async function onExecuteUrgency(req, res) {
await refreshTokenInFirestore(req);
const inputs = req.body?.workflow?.actionInvocation?.inputs || {};
const description = inputs.ticketDescription?.stringValues?.[0] || '';
let urgencyLevel = detectKeywordUrgency(description);
try {
const response = await ai.models.generateContent({
model: 'gemini-3.8-flash',
contents: `Evaluate the business impact and time sensitivity of this support ticket description and classify its urgency:\n\n${description}`,
config: {
responseMimeType: 'text/x.enum',
responseSchema: {
type: Type.STRING,
enum: ['High', 'Normal'],
},
},
});
const candidate = (response.text || '').trim();
if (candidate === 'High' || candidate === 'Normal') {
urgencyLevel = candidate;
}
} catch (err) {
console.error('Gemini fallback to keyword matching:', err.message);
}
res.status(200).json({
hostAppAction: {
workflowAction: {
returnOutputVariablesAction: {
variables: {
urgencyLevel: {
stringValues: [urgencyLevel],
},
},
},
},
},
});
}
EOF
portal.js — Quick Portal के यूज़र इंटरफ़ेस (यूआई) और triggers.fire डिस्पैचर के साथ काम करता है
वेब पोर्टल पर सेवा देने और Google Workspace Studio को टिकट सबमिट करने के लिए, portal.js बनाएं:
renderPortal(GET /): यहstudio_triggersFirestore कलेक्शन से क्वेरी करता है, ताकि यह दिखाया जा सके कि Google Workspace Studio के कितने ट्रिगर रजिस्टर किए गए हैं. साथ ही, यह एचटीएमएल टिकट सबमिट करने का फ़ॉर्म दिखाता है.submitTicket(POST /api/submit-ticket): यहstudio_triggersमें मौजूद सभी चालू ट्रिगर दस्तावेज़ों को दोहराता है. साथ ही,ticketTitleऔरticketDescriptionआउटपुट वैरिएबल और यूनीकrequestIdके साथ Google Workspace Studiotriggers.fireएंडपॉइंट (https://workspacestudio.googleapis.com/v1/triggers/{triggerId}:fire) को शुरू करता है. इसके बाद, टिकट कोsupport_ticketsFirestore कलेक्शन में सेव करता है.
cat << 'EOF' > portal.js
import { triggersCollection, ticketsCollection } from './firestore.js';
// Support Quick Portal UI
export async function renderPortal(req, res) {
let activeCount = 0;
try {
const snapshot = await triggersCollection.get();
activeCount = snapshot.size;
} catch (err) {
console.error('Error reading studio_triggers collection:', err.message);
}
res.status(200).send(`<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Support Quick Portal</title>
<style>
body { font-family: Arial, sans-serif; padding: 24px; max-width: 540px; margin: auto; color: #202124; }
.badge { background: #e8f0fe; color: #1967d2; padding: 8px 12px; border-radius: 6px; font-size: 14px; margin-bottom: 16px; }
label { font-weight: bold; display: block; margin-top: 16px; }
input, textarea { width: 100%; margin-top: 6px; padding: 10px; box-sizing: border-box; border: 1px solid #dadce0; border-radius: 4px; }
button { background-color: #1a73e8; color: white; border: none; padding: 10px 18px; margin-top: 16px; font-weight: bold; cursor: pointer; border-radius: 4px; }
button:hover { background-color: #1557b0; }
#status { margin-top: 16px; font-weight: bold; }
</style>
</head>
<body>
<h2>Support Quick Portal</h2>
<div class="badge">
Active Google Workspace Studio triggers in Firestore (<code>studio_triggers</code>):
<strong id="trigger-count">${activeCount}</strong>
</div>
<p>Submit a support ticket below to fire your Google Workspace Studio flow.</p>
<label for="title">Ticket Title</label>
<input type="text" id="title" placeholder="e.g. Database failure">
<label for="description">Issue Description</label>
<textarea id="description" rows="4" placeholder="Describe the issue..."></textarea>
<button onclick="submitTicket()">Submit Ticket</button>
<div id="status"></div>
<script>
async function submitTicket() {
const title = document.getElementById('title').value.trim();
const description = document.getElementById('description').value.trim();
const statusEl = document.getElementById('status');
if (!title || !description) {
statusEl.style.color = '#d93025';
statusEl.textContent = 'Please fill out both fields.';
return;
}
statusEl.style.color = '#188038';
statusEl.textContent = 'Submitting ticket...';
try {
const res = await fetch('/api/submit-ticket', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title, description }),
});
const data = await res.json();
if (data.ok) {
statusEl.textContent =
'Ticket saved to Firestore! Fired ' + data.triggersFired + ' Google Workspace Studio trigger(s).';
} else {
statusEl.style.color = '#d93025';
statusEl.textContent = 'Error: ' + (data.error || 'Unknown error');
}
} catch (err) {
statusEl.style.color = '#d93025';
statusEl.textContent = 'Request failed: ' + err.message;
}
}
</script>
</body>
</html>`);
}
// Portal Form Submission -> Fire Active Google Workspace Studio Triggers
export async function submitTicket(req, res) {
const title = req.body?.title || 'Untitled Ticket';
const description = req.body?.description || '';
const results = [];
try {
const snapshot = await triggersCollection.get();
for (const doc of snapshot.docs) {
const trigger = doc.data();
if (!trigger.triggerId || !trigger.userOAuthToken) continue;
const response = await fetch(
`https://workspacestudio.googleapis.com/v1/triggers/${encodeURIComponent(trigger.triggerId)}:fire`,
{
method: 'POST',
headers: {
Authorization: `Bearer ${trigger.userOAuthToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'triggers/' + trigger.triggerId,
outputs: {
ticketTitle: { stringValues: [title] },
ticketDescription: { stringValues: [description] },
},
requestId:
'req_' + Date.now() + '_' + Math.floor(Math.random() * 1000),
}),
}
);
results.push({ triggerId: trigger.triggerId, status: response.status });
}
await ticketsCollection.add({
title,
description,
triggersFired: results.length,
createdAt: new Date().toISOString(),
});
res.status(200).json({ ok: true, triggersFired: results.length, results });
} catch (err) {
console.error('Error in /api/submit-ticket:', err.message);
res.status(500).json({ ok: false, error: err.message });
}
}
EOF
index.js — Express सर्वर का एंट्री पॉइंट
अपने पोर्टल के रास्तों और Google Workspace Studio के वेबहुक एंडपॉइंट को एक साथ जोड़ने के लिए index.js बनाएं. इसके लिए, Express HTTP सर्वर को PORT पर लिसन करें (Cloud Run पर डिफ़ॉल्ट 8080):
cat << 'EOF' > index.js
import express from 'express';
import { onConfigTrigger, onManageTrigger } from './starter.js';
import { onConfigUrgency, onExecuteUrgency } from './action.js';
import { renderPortal, submitTicket } from './portal.js';
const app = express();
app.use(express.json());
// Support Quick Portal routes
app.get('/', renderPortal);
app.post('/api/submit-ticket', submitTicket);
// Google Workspace Studio Custom Starter Step webhooks
app.post('/onConfigTrigger', onConfigTrigger);
app.post('/onManageTrigger', onManageTrigger);
// Google Workspace Studio Custom Action Step webhooks
app.post('/onConfigUrgency', onConfigUrgency);
app.post('/onExecuteUrgency', onExecuteUrgency);
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`Support Extension listening on port ${PORT}`);
});
EOF
4. Cloud Run पर डिप्लॉय करना और ऐड-ऑन इंस्टॉल करना
इस चरण में, Node.js सेवा को Cloud Run पर डिप्लॉय किया जाता है. साथ ही, Google Workspace ऐड-ऑन को शुरू करने वाले व्यक्ति और Firestore को IAM अनुमतियां दी जाती हैं. इसके अलावा, एजेंट प्लैटफ़ॉर्म के रनटाइम ऐक्सेस की अनुमति दी जाती है, deployment.json मेनिफ़ेस्ट जनरेट किया जाता है, और ऐड-ऑन डिप्लॉयमेंट इंस्टॉल किया जाता है.
- अपने प्रोजेक्ट और Firestore कलेक्शन के एनवायरमेंट वैरिएबल के साथ,
support-extensionसेवा को Cloud Run पर डिप्लॉय करें:gcloud run deploy support-extension \ --source . \ --region us-central1 \ --allow-unauthenticated \ --set-env-vars="GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project),FIRESTORE_TRIGGERS_COLLECTION=studio_triggers,FIRESTORE_TICKETS_COLLECTION=support_tickets" \ --quiet - Google Workspace Studio को आपके वेबुक एंडपॉइंट कॉल करने की अनुमति देने के लिए, Google Workspace ऐड-ऑन के सेवा खाते को Cloud Run सेवा पर
roles/run.invokerदें:ADDON_SA=$(gcloud workspace-add-ons get-authorization --format="value(serviceAccountEmail)") gcloud run services add-iam-policy-binding support-extension \ --region=us-central1 \ --member="serviceAccount:${ADDON_SA}" \ --role="roles/run.invoker" \ --quiet - Cloud Run रनटाइम सेवा खाते को ये अनुमतियां दें:
roles/datastore.user(studio_triggersऔरsupport_ticketsFirestore कलेक्शन को पढ़ने और लिखने के लिए) औरroles/aiplatform.user(Gemini Enterprise Agent Platform पर Gemini को कॉल करने के लिए):PROJECT_ID=$(gcloud config get-value project) PROJECT_NUMBER=$(gcloud projects describe "${PROJECT_ID}" --format="value(projectNumber)") RUNTIME_SA=$(gcloud run services describe support-extension --region=us-central1 --format="value(spec.template.spec.serviceAccountName)") RUNTIME_SA=${RUNTIME_SA:-"${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"} gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:${RUNTIME_SA}" \ --role="roles/datastore.user" \ --condition=None \ --quiet gcloud projects add-iam-policy-binding "${PROJECT_ID}" \ --member="serviceAccount:${RUNTIME_SA}" \ --role="roles/aiplatform.user" \ --condition=None \ --quiet - डिप्लॉय किए गए Cloud Run यूआरएल को वापस पाएं और
deployment.jsonमेनिफ़ेस्ट जनरेट करें. इसमेंsupportTicketTrigger(workflowTrigger) औरurgencyDetectorStep(workflowAction) एलिमेंट तय किए गए हों:SERVICE_URL=$(gcloud run services describe support-extension --region=us-central1 --format="value(status.url)") cat << EOF > deployment.json { "oauthScopes": [ "https://www.googleapis.com/auth/workspace.studio.trigger", "https://www.googleapis.com/auth/userinfo.email" ], "addOns": { "common": { "name": "Support Extension", "logoUrl": "https://www.gstatic.com/images/branding/productlogos/buganizer/v1/192px.svg" }, "studio": { "flows": { "workflowElements": [ { "id": "supportTicketTrigger", "state": "ACTIVE", "name": "New Support Ticket", "description": "Fires when someone submits a ticket in the Support Quick Portal.", "workflowTrigger": { "inputs": [], "outputs": [ { "id": "ticketTitle", "description": "Ticket Title", "cardinality": "SINGLE", "dataType": { "basicType": "STRING" } }, { "id": "ticketDescription", "description": "Ticket Description", "cardinality": "SINGLE", "dataType": { "basicType": "STRING" } } ], "onConfigFunction": "${SERVICE_URL}/onConfigTrigger", "onManageFunction": "${SERVICE_URL}/onManageTrigger" } }, { "id": "urgencyDetectorStep", "state": "ACTIVE", "name": "Detect Urgency", "description": "Evaluates the ticket description to detect High or Normal urgency.", "workflowAction": { "inputs": [ { "id": "ticketDescription", "description": "Description to scan", "cardinality": "SINGLE", "dataType": { "basicType": "STRING" } } ], "outputs": [ { "id": "urgencyLevel", "description": "Detected Urgency (High / Normal)", "cardinality": "SINGLE", "dataType": { "basicType": "STRING" } } ], "onConfigFunction": "${SERVICE_URL}/onConfigUrgency", "onExecuteFunction": "${SERVICE_URL}/onExecuteUrgency" } } ] } }, "httpOptions": { "authorizationHeader": "SYSTEM_ID_TOKEN" } } } EOF - अपने खाते के लिए, Google Workspace ऐड-ऑन डिप्लॉयमेंट बनाएं (या बदलें) और उसे इंस्टॉल करें. साथ ही, सहायता पोर्टल के यूआरएल को प्रिंट करें:
gcloud workspace-add-ons deployments create support-extension --deployment-file=deployment.json || \ gcloud workspace-add-ons deployments replace support-extension --deployment-file=deployment.json gcloud workspace-add-ons deployments install support-extension echo "Support Quick Portal URL: ${SERVICE_URL}"
5. Google Workspace Studio में, कस्टम चरणों को टेस्ट करना
- Google Workspace Studio खोलें. अगर यह पहले से खुला है, तो ब्राउज़र टैब को रीफ़्रेश करें. इसके बाद, नया फ़्लो पर क्लिक करें.
- स्टार्टर चुनें > सहायता एक्सटेंशन > नया सहायता टिकट पर क्लिक करें.
- चरण जोड़ें (
+) > सहायता एक्सटेंशन > जल्द कार्रवाई करने की ज़रूरत का पता लगाएं पर क्लिक करें. सोर्स का ब्यौरा फ़ील्ड में, + वैरिएबल पर क्लिक करें. इसके बाद, टिकट का ब्यौरा चुनें. - चरण जोड़ें (
+) पर क्लिक करें. इसके बाद, Chat > मुझे Chat में सूचना दें चरण जोड़ें. इसमें मैसेज में टिकट का टाइटल, ज़रूरत का लेवल, और टिकट का ब्यौरा वैरिएबल शामिल करें. - सबसे ऊपर दाएं कोने में मौजूद, फ़्लो को चालू करें पर टॉगल करें. Google Workspace Studio, Cloud Run पर मौजूद आपके
/onManageTriggerएंडपॉइंट को तुरंत कॉल करता है. यहstudio_triggersकलेक्शन में, चालू ट्रिगर सदस्यता लिखता है. - नए टैब में, Support Quick Portal का यूआरएल (
https://support-extension-...run.app) खोलें. पुष्टि करें कि पोर्टल में1Firestore में ट्रिगर चालू है दिख रहा हो. इसके बाद, Gemini 3.8 Flash (gemini-3.8-flash) के क्लासिफ़िकेशन की जांच करने के लिए, दो टिकट सबमिट करें:- ज़्यादा असर डालने वाली समस्या (टिकट का टाइटल:
London office lockout, समस्या का ब्यौरा:All 500 employees in the London office are locked out of their workstations 20 minutes before the board presentation.):urgentयाblockerजैसे हार्डकोड किए गए कीवर्ड के बिना भी,gemini-3.8-flashइस टिकट कोHighके तौर पर क्लासिफ़ाई करता है. - रूटीन टिकट (टिकट का टाइटल:
Conference room adapters, समस्या का ब्यौरा:Could we order two extra HDMI adapters for the third-floor conference room next month?):gemini-3.8-flashइस टिकट कोNormalके तौर पर क्लासिफ़ाई करता है.
- ज़्यादा असर डालने वाली समस्या (टिकट का टाइटल:
- Google Chat और Google Workspace Studio के गतिविधि टैब में जाकर पुष्टि करें कि आपका फ़्लो,
Urgency Level: HighऔरUrgency Level: Normalवाले दोनों टिकट के लिए चला हो.
6. व्यवस्थित करें
अपने Google Cloud खाते पर लगने वाले शुल्क से बचने के लिए, Cloud Shell में डिप्लॉय किए गए संसाधनों को हटाएं:
gcloud workspace-add-ons deployments uninstall support-extension
gcloud workspace-add-ons deployments delete support-extension --quiet
gcloud run services delete support-extension --region=us-central1 --quiet
gcloud firestore databases delete --database="(default)" --quiet
7. बधाई हो!
आपने Gemini Enterprise Agent Platform पर Firestore, Cloud Run, और Gemini 3.8 Flash का इस्तेमाल करके, Google Workspace Studio के लिए Node.js HTTP एक्सटेंशन बनाया, उसे डिप्लॉय किया, और उसकी जांच की!
हमने क्या-क्या कवर किया है
workflowTriggerऔरworkflowActionएलिमेंट के साथ, Google Workspace Studio के एचटीटीपी ऐड-ऑन मेनिफ़ेस्ट (deployment.json) को कॉन्फ़िगर करना.- यह कुकी, Google Workspace Studio
workflowTriggerकी सदस्यताओं कोstudio_triggersFirestore कलेक्शन में सेव करती है. साथ ही, पोर्टल सबमिशन कोsupport_ticketsमें लॉग करती है, ताकि Cloud Run की स्केलिंग और फिर से डिप्लॉयमेंट के दौरान ट्रिगर काम करते रहें. - Gemini Enterprise Agent Platform पर, Gemini 3.8 Flash (
gemini-3.8-flash) की मदद से सहायता टिकटों को कैटगरी में बांटने वालाworkflowActionचरण बनाना. इसमें कीवर्ड मैचिंग फ़ॉलबैक की सुविधा भी शामिल है.