1. مقدمه
هدف این نرم افزار کد این است که بفهمید چگونه یک تابع ابری بنویسید تا به آپلود فایل CSV در فضای ذخیره سازی ابری واکنش نشان دهید، محتوای آن را بخوانید و از آن برای به روز رسانی یک برگه Google با استفاده از Sheets API استفاده کنید.
این را می توان به عنوان اتوماسیون یک مرحله دستی "وارد کردن به عنوان CSV" در نظر گرفت. این اطمینان حاصل می کند که می توانید داده ها (شاید توسط تیم دیگری تولید شده است) را در یک صفحه گسترده به محض در دسترس بودن تجزیه و تحلیل کنید.
این چیزی است که پیاده سازی به نظر می رسد:
2. راه اندازی و الزامات
تنظیم محیط خود به خود
- به کنسول Cloud وارد شوید و یک پروژه جدید ایجاد کنید یا از یک موجود استفاده مجدد کنید. (اگر قبلاً یک حساب Gmail یا G Suite ندارید، باید یک حساب ایجاد کنید .)
شناسه پروژه را به خاطر بسپارید، یک نام منحصر به فرد در تمام پروژه های Google Cloud (نام بالا قبلاً گرفته شده است و برای شما کار نخواهد کرد، متأسفیم!). بعداً در این آزمایشگاه کد به عنوان PROJECT_ID
نامیده خواهد شد.
- در مرحله بعد، برای استفاده از منابع Google Cloud، باید صورتحساب را در Cloud Console فعال کنید .
اجرا کردن از طریق این کد لبه نباید هزینه زیادی داشته باشد، اگر اصلاً باشد. حتماً دستورالعملهای موجود در بخش «تمیز کردن» را دنبال کنید که به شما توصیه میکند چگونه منابع را خاموش کنید تا بیش از این آموزش متحمل صورتحساب نشوید. کاربران جدید Google Cloud واجد شرایط برنامه آزمایشی رایگان 300 دلاری هستند.
3. یک Google Sheet ایجاد و پیکربندی کنید و API را فعال کنید
ابتدا اجازه دهید یک سند Sheets جدید ایجاد کنیم (این برگه می تواند متعلق به هر کاربری باشد). پس از ایجاد، شناسه آن را به خاطر بسپارید. به عنوان یک متغیر محیطی برای تابعی که می نویسیم استفاده می شود:
از کنسول GCP ، با رفتن به بخش «APIs and Services» و سپس «API Library»، API کاربرگنگار Google را در پروژه تازه ایجاد شده خود فعال کنید:
در بخش «IAM & admin»، به «حسابهای خدمات» بروید و ایمیل حساب سرویس پیشفرض App Engine را یادداشت کنید. باید به شکل your-project-id@appspot.gserviceaccount.com
باشد. البته شما همچنین می توانید حساب سرویس خود را که به این عمل اختصاص داده شده است ایجاد کنید.
در نهایت، به سادگی با استفاده از دکمه «اشتراکگذاری»، به صفحهگسترده خود امتیاز ویرایش حساب کاربری را بدهید:
با این تنظیمات، اکنون میتوانیم تابع Cloud خود را بنویسیم و آن را برای استفاده از این حساب سرویس پیکربندی کنیم. میتواند در این سند صفحهگسترده که به تازگی ایجاد کردهایم بنویسد.
4. یک سطل ذخیره سازی ایجاد کنید
بیایید سطلی را ایجاد کنیم که عملکرد ابری ما برای فایلهای CSV جدید نظارت میکند.
در کنسول، از منوی سمت چپ برای پیمایش به "Storage" استفاده کنید... :
... و یک سطل جدید به نام csv2sheet-POSTFIX
ایجاد کنید (POSTFIX را با چیزی منحصربفرد جایگزین کنید) با سایر تنظیمات که روی مقادیر پیش فرض تنظیم شده اند:
5. عملکرد Cloud را ایجاد کنید
اکنون میتوانیم یک تابع Cloud به نام csv2sheet
ایجاد کنیم که در آپلود فایلها در یک سطل ذخیرهسازی ابری خاص فعال میشود. کد در Node.js 8 با توابع async با استفاده از ویرایشگر درون خطی مستقیماً در Cloud Console نوشته میشود:
مطمئن شوید که Trigger را روی "Cloud Storage" تنظیم کرده اید و نام سطل را با نامی که در مرحله قبل ایجاد کرده اید تنظیم کنید.
همچنین نقطه ورودی را برای تابعی که می خواهیم در csv2sheet
بنویسیم به روز کنید:
حالا بدنه تابع را به زیر تغییر دهید:
- از Cloud Storage و Sheets API استفاده کنید
- تابع
csv2sheet
را به عنوانasync
علامت گذاری کنید -
fileName
را از ابرداده رویداد Cloud Storage نگه دارید و نامی برای برگه جدیدی که ایجاد می کنیم استخراج کنید:
const {google} = require("googleapis");
const {Storage} = require("@google-cloud/storage")
exports.csv2sheet = async (data, context) => {
var fileName = data.name;
// basic check that this is a *.csv file, etc...
if (!fileName.endsWith(".csv")) {
console.log("Not a .csv file, ignoring.");
return;
}
// define name of new sheet
const sheetName = fileName.slice(0, -4);
// TODO!
};
استفاده از async
در اینجا برای استفاده از await
لازم است همانطور که در یک لحظه خواهیم دید.
چند گزینه مهم هنگام ایجاد این عملکرد عبارتند از (روی پیوند "بیشتر" در پایین صفحه کلیک کنید):
- از منوی کشویی برای انتخاب حساب سرویس مورد بحث در بالا استفاده کنید
- یک متغیر محیطی به نام
SPREADSHEET_ID
تعریف کنید که باید با سند برگه ای که قبلا ایجاد کرده اید مطابقت داشته باشد:
به عنوان آخرین مرحله راهاندازی، در اینجا محتوای package.json
با APIهای Cloud Storage و Google Sheet بهعنوان دو وابستگی است که استفاده میکنیم (از تب PACKAGE.JSON ویرایشگر داخلی کنسول استفاده کنید):
{
"name": "csv2sheet",
"version": "0.0.42",
"dependencies": {
"googleapis": "^51.0.0",
"@google-cloud/storage": "^5.0.1"
}
}
هنگامی که همه چیز را همانطور که توضیح داده شد پیکربندی کردید، ادامه دهید، روی "ایجاد" کلیک کنید! پس از یک دقیقه کوتاه تابع شما باید ایجاد و مستقر شود.
6. auth و Sheets API را راه اندازی کنید
قبل از اینکه با استفاده از ویرایشگر درون خطی، کد دیگری را در تابع Cloud خود بنویسیم، باید ایجاد یک Google Client API با دامنههای Storage و Sheet مناسب را مسدود کنیم (به یاد داشته باشید، این بخشی از یک تابع async
است).
در ویرایشگر تابع کنسول، روی "EDIT" کلیک کنید و کد زیر را به بدنه تابع csv2sheet
خود اضافه کنید:
// block on auth + getting the sheets API object
const auth = await google.auth.getClient({
scopes: [
"https://www.googleapis.com/auth/spreadsheets",
"https://www.googleapis.com/auth/devstorage.read_only"
]
});
از آنجا می توانیم یک سرویس گیرنده Sheets API ایجاد کنیم:
const sheetsAPI = google.sheets({version: 'v4', auth});
7. از Sheets API برای ایجاد یک برگه خالی استفاده کنید
با یک کلاینت Sheets API میتوانیم یک برگه ساده جدید در سند خود ایجاد کنیم، اما قبل از اینکه به ادامهتر برویم، در اینجا یک یادداشت سریع در مورد واژگان وجود دارد:
- صفحه گسترده سند واقعی است و با شناسه آن ارجاع داده می شود (در بالا بحث شد و در URL سند قابل مشاهده است)
- برگه یکی از برگههای سند است و میتوان آن را با نام آن (نام برگه) یا شناسهای که پس از ایجاد برگه ایجاد میشود ارجاع داد.
با در نظر گرفتن این موضوع، در اینجا تابعی با استفاده از سرویس گیرنده Sheets API برای ایجاد یک برگه خالی در موقعیت 2 (معمولاً پس از "Sheet1" پیش فرض)، با 26 ستون، 2000 ردیف، با سطر اول ثابت شده است (آن را با استفاده از آن به تابع خود اضافه کنید. ویرایشگر درون خطی):
function addEmptySheet(sheetsAPI, sheetName) {
return new Promise((resolve, reject) => {
const emptySheetParams = {
spreadsheetId: process.env.SPREADSHEET_ID,
resource: {
requests: [
{
addSheet: {
properties: {
title: sheetName,
index: 1,
gridProperties: {
rowCount: 2000,
columnCount: 26,
frozenRowCount: 1
}
}
}
}
]
}
};
sheetsAPI.spreadsheets.batchUpdate( emptySheetParams, function(err, response) {
if (err) {
reject("The Sheets API returned an error: " + err);
} else {
const sheetId = response.data.replies[0].addSheet.properties.sheetId;
console.log("Created empty sheet: " + sheetId);
resolve(sheetId);
}
}
);
});
}
توجه داشته باشید که چگونه به جای کدگذاری سخت مرجع به صفحه گسترده، به متغیر محیطی SPREADSHEET_ID
ایجاد شده قبلی تکیه می کنیم.
برای درخواستهای بیشتر به این برگه خاص، باید sheetId
به خاطر بسپاریم. همچنین، نام برگه باید منحصر به فرد باشد و اگر از قبل برگه ای به نام sheetName
وجود داشته باشد، ایجاد ناموفق خواهد بود.
تابع batchUpdate
در Sheets API یک روش متداول برای تعامل با اسناد است و در اینجا توضیح داده شده است.
8. خواندن داده ها از یک فایل CSV ذخیره سازی
اکنون که جایی برای تخلیه داده های خود داریم، بیایید عملکرد ابری خود را در ویرایشگر درون خطی توسعه دهیم و از Cloud Storage API استفاده کنیم تا برویم و داده های واقعی را از فایلی که به تازگی آپلود شده است بگیریم و آن را در یک رشته ذخیره کنیم:
function readCSVContent(sheetsAPI, file, sheetName) {
return new Promise((resolve, reject) => {
const storage = new Storage();
let fileContents = new Buffer('');
storage.bucket(file.bucket).file(file.name).createReadStream()
.on('error', function(err) {
reject('The Storage API returned an error: ' + err);
})
.on('data', function(chunk) {
fileContents = Buffer.concat([fileContents, chunk]);
})
.on('end', function() {
let content = fileContents.toString('utf8');
console.log("CSV content read as string : " + content );
resolve(content);
});
});
}
9. صفحه جدید ایجاد شده را پر کنید
اکنون زمان آن رسیده است که برگه ای را که با استفاده از همان API مشتری Sheet ایجاد کرده ایم و داده هایی که به تازگی جمع آوری کرده ایم، پر کنیم. از این فرصت استفاده میکنیم و به ستونهای برگه نیز سبک اضافه میکنیم (تغییر اندازه قلم ردیف بالا و پررنگ کردن آن):
function populateAndStyle(sheetsAPI, theData, sheetId) {
return new Promise((resolve, reject) => {
// Using 'batchUpdate' allows for multiple 'requests' to be sent in a single batch.
// Populate the sheet referenced by its ID with the data received (a CSV string)
// Style: set first row font size to 11 and to Bold. Exercise left for the reader: resize columns
const dataAndStyle = {
spreadsheetId: process.env.SPREADSHEET_ID,
resource: {
requests: [
{
pasteData: {
coordinate: {
sheetId: sheetId,
rowIndex: 0,
columnIndex: 0
},
data: theData,
delimiter: ","
}
},
{
repeatCell: {
range: {
sheetId: sheetId,
startRowIndex: 0,
endRowIndex: 1
},
cell: {
userEnteredFormat: {
textFormat: {
fontSize: 11,
bold: true
}
}
},
fields: "userEnteredFormat(textFormat)"
}
}
]
}
};
sheetsAPI.spreadsheets.batchUpdate(dataAndStyle, function(err, response) {
if (err) {
reject("The Sheets API returned an error: " + err);
} else {
console.log(sheetId + " sheet populated with " + theData.length + " rows and column style set.");
resolve();
}
});
});
}
این کد باید به عملکرد Cloud ما اضافه شود که اکنون 99٪ کامل شده است!
توجه داشته باشید که چگونه دادهها و استایلها بهعنوان چندین requests
در یک تماس batchUpdate
Sheets API ترکیب میشوند. این باعث بهروزرسانی کارآمدتر و اتمیتر میشود.
همچنین توجه داشته باشید که محدوده ویرایشی را تعریف می کنیم که با اندازه صفحه ای که ایجاد کرده ایم مطابقت داشته باشد. این بدان معناست که محتوایی که بیش از 26 ستون باشد (مقدار columnCount
که هنگام ایجاد برگه استفاده می شود) با این کد خاص شکست می خورد.
اگر همه چیز خوب پیش رفت، در این مرحله می توانید:
- عملکرد به روز شده را ذخیره کنید
- یک فایل CSV را در سطل بیندازید
- داده های مربوطه را در صفحه گسترده خود مشاهده کنید!
10. کنار هم قرار دادن همه و آزمایش جریان
فراخوانی های توابعی که به تازگی در مورد آن صحبت کردیم را می توان به عنوان تماس های مسدود کننده متوالی در تابع اصلی csv2sheet
انجام داد:
const sheetId = await addEmptySheet(sheetsAPI, sheetName);
const theData = await readCSVContent(sheetsAPI, data, sheetName);
await populateAndStyle(sheetsAPI, theData, sheetId);
اگر به کد منبع تابع کامل نیاز دارید، در اینجا موجود است (احتمالاً دریافت همه آن در یک مجموعه آسان تر است).
هنگامی که همه چیز درست شد، به سادگی یک فایل CSV را در سطل سمت راست آپلود کنید و ببینید صفحه گسترده خود را با یک صفحه جدید حاوی محتوای فایل به روز می کند. در اینجا یک نمونه فایل CSV وجود دارد، اگر یک فایل مفید ندارید.
سعی کنید چندین فایل را در سطل آپلود کنید تا ببینید چه اتفاقی می افتد!
11. همین! زمان تخریب زیرساخت ها است
شوخی دارم، هیچ زیرساختی برای خراب کردن وجود ندارد، این همه بدون سرور انجام شد!
در صورت تمایل می توانید تابع ابر و سطلی را که ایجاد کرده اید یا حتی کل پروژه را حذف کنید.
12. بعد چی؟
این به پایان میرسد که این لبه کد شما را از طریق مراحل گوش دادن به آپلودهای یک سطل فضای ذخیرهسازی ابری در یک تابع ابری برای بهروزرسانی یک برگه Google با استفاده از API مناسب راهنمایی میکند.
در اینجا چند مرحله پیگیری وجود دارد:
- راهنمای نحوه عملکرد Cloud Functions را بررسی کنید (شامل برخی از بهترین شیوه ها)
- یکی از آموزشهای Cloud Functions را طی کنید
- Google Sheets API را بیشتر کاوش کنید
اگر با این کد لبه با مشکل مواجه شدید، با استفاده از پیوند در گوشه سمت چپ پایین، هر مشکلی را گزارش دهید.
بازخورد شما قابل تقدیر است!