استفاده از APIهای Google Drive در جاوااسکریپت

گردآوری و تالیف : ارسطو عباسی
تاریخ انتشار : 18 مرداد 1398
دسته بندی ها : جاوا اسکریپت

گوگل مجموعه بسیار بزرگی از APIها را در اختیار دارد که ممکن است برای انجام کارهای مختلفی توسط شما نیز استفاده شده باشد. از APIهای نقشه گوگل گرفته تا تقویم و Google Analytics و… . اما امروز قصد داریم در ارتباط با یکی از منحصر به فردترین محصولات گوگل یعنی Google Drive و ابزارهای آن صحبت کنیم. 

در این مطلب قصد آشنا کردن شما با شیوه استفاده از APIهای گوگل درایو با استفاده از جاوااسکریپت را داریم. در این مطلب ما از نودجی‌اس استفاده خواهیم کرد به همین دلیل نیاز است که شما نیز آن را روی کامپیوترتان نصب کنید. همچنین برای اینکه بتوانید قدم به قدم با این آموزش جلو بروید ابتدا یک دایرکتوری جدید ایجاد کرده و دستور npm init -y را در آن اجرا کنید. همچنین فایل index.js را در داخل همان دایرکتوری ایجاد کنید.

احرازهویت

قبل از اینکه بتوانیم از APIهای گوگل استفاده کنیم نیاز است که فرایند احرازهویت را طی نماییم. برای انجام اینکار ابتدا وارد console.developers.google.com شده و یک پروژه را انتخاب کنید، همچنین می‌توانید یک پروژه جدید را ایجاد نمایید. پروژه‌ها برای مشاهده فعالیت‌های API و انجام فرایندهای پرداخت برای اپلیکیشن‌های بزرگ استفاده می‌کند. در این آموزش نیازی به انجام پرداخت و… نیست. 

گزینه اول برای احرازهویت: API Key

این مورد یکی از ساده‌ترین راه‌ها برای احرازهویت است چرا که قرار است تنها با یک رشته متنی تعامل داشته باشید. البته استفاده از این حالت کمترین میزان امنیت را به شما می‌دهد، بنابراین برای اپلیکیشن‌های خاص نمی‌تواند روشی مناسب باشد. 

گزینه دوم برای احرازهویت: OAuth 2.0

اگر نیاز است که کاربران برای استفاده از اپلیکیشن شما مجوزهایی را صادر کنند می‌توانید از استاندارد OAuth 2.0 استفاده کنید. این استاندارد از کاربران درخواست ارائه مجوز به اپلیکیشن شما را می‌کند، تا قبل از انجام این کار شما نمی‌توانید از طریق APIها هیچ کاری را انجام دهید. استفاده از چنین استانداردی برای اپلیکیشن‌های Front-End یک امر الزامی است اما برای ما که قصد ساخت اپلیکیشن Server-Side را داریم لزومی ندارد.

گزینه سوم برای احرازهویت: اکانت سرویس

گزینه نهایی برای احرازهویت استفاده از یک اکانت سرویس است: برای استفاده از این قابلیت وارد این صفحه شده و روی Create credentials و بعد service account key کلیک کنید. زمانی که این کارها را انجام دادید یک فایل JSON با ساختار زیر برای شما برگشت داده می‌شود:

{
  "type": "service_account",
  "project_id": "",
  "private_key_id": "",
  "private_key": "",
  "client_email": "",
  "client_id": "",
  "auth_uri": "",
  "token_uri": "",
  "auth_provider_x509_cert_url": "",
  "client_x509_cert_url": ""
}

این فایل را با نام credentials.json در دایرکتوری اصلی پروژه ذخیره کنید.

فعال‌سازی APIها

بعد از انجام این کار حال برای استفاده از APIها نیاز است که آن‌ها را فعال کنید. ابتدا وارد کتابخانه‌ API گوگل شوید، به صورت پیشفرض در این قسمت هیچ API فعالی وجود ندارد. پس باید براساس نیازتان APIهایی را فعال کنید. از آنجایی که ما قصد استفاده از Google Drive و Google Sheets را داریم پس نیاز است که APIهای این دو مورد را فعال کنیم. برای Google Drive وارد این صفحه و برای Google Sheets وارد این صفحه شده و APIها را فعال کنید. 

به اشتراک گذاری فایل‌ها

برای اینکه بتوانید از روش اکانت سرویس برای احرازهویت استفاده کنید نیاز است که به اکانت سرویس قابلیت دسترسی بدهید. برای انجام این کار ابتدا فایل credentials.json را باز کرده و مقدار کلید client_email را کپی کنید. معمولا این ایمیل آدرس چیزی شبیه به زیر خواهد بود:

service-account@projectname-123456.iam.gserviceaccount.com

حال در گوگل درایو یک فولدر جدید ایجاد کرده و آن را با ایمیل مربوط به client_email به اشتراک بگذارید. این کار تنها قابلیت دسترسی به این ایمیل را خواهد داد. به همین دلیل است که این روش نسبت به روش اول احرازهویت امن‌تر است.

نصب ماژول

در نهایت قبل از اینکه شروع به کدنویسی بکنیم نیاز است که پکیج googleapis را نصب کنیم. برای انجام اینکار ترمینال را در دایرکتوری پروژه باز کرده و دستور npm i googleapis را وارد کنید. بعد از آن در فایل جاوااسکریپت که قبلا ساخته بودیم دستور require زیر را وارد کنید:

const { google } = require('googleapis');

حال می‌توانیم سراغ کدنویسی برویم.

شروع کار با Google Drive API

دسترسی‌ها و Scopeها

اولین کاری که باید انجام دهیم این است که Scopeهای مورد نظرمان را تعیین نماییم. برای اینکار می‌توانید لیست کاملی از Scopeها را در این صفحه مشاهده کنید. برای برنامه‌ای که ما قصد ساخت‌ش را داریم استفاده از Scope زیر کافی خواهد بود:

const scopes = [
  'https://www.googleapis.com/auth/drive'
];

حال باید credentialهای مرتبط را از فایل credentials.json وارد پروژه کنیم. بعد از انجام این کار تمام فرایندهای دسترسی و احرازهویت را انجام داده‌ایم.

const { google } = require('googleapis');
const credentials = require('./credentials.json');
const scopes = [
  'https://www.googleapis.com/auth/drive'
];
const auth = new google.auth.JWT(
  credentials.client_email, null,
  credentials.private_key, scopes
);

اگر دقت کنید می‌بینید که ما برای ایجاد JSON Web Token از google.auth.JWT استفاده کرده‌ایم.

تست کدها

قبل از اینکه ویژگی‌های پیچیده‌تری را بررسی کنیم بیایید درست کار کردن کدها را تست نماییم. برای انجام این کار قصد داریم تا از طریق متد drive.files.list قابلیت مشاهده تمام فایل‌های داخل گوگل درایو را تست کنیم.

drive.files.list({}, (err, res) => {
  if (err) throw err;
  const files = res.data.files;
  if (files.length) {
  files.map((file) => {
    console.log(file);
  });
  } else {
    console.log('No files found');
  }
});

اگر همه چیز به درستی کار کند شما باید در خروجی یکسری شی‌ JSON را مشاهده کنید اگر خروجی No files found نیز ارائه شد باز هم کدها مشکلی ندارند و تنها نشان از این می‌دهد که فایلی با دسترسی کاربر وجود ندارد.

افزودن ورودی‌های جدید

اگر دقت کنید متوجه می‌شوید که ما در مثال بالا drive.files.list را بدون هیچگونه آرگومان ورودی و تنها با یک شی خالی اجرا کردیم. اما می‌توان ورودی‌های دیگری را برای این متد در نظر گرفت. یکی از ورودی‌های کاربردی fields است. برای مشاهده تمام فیلدها می‌توانید شیء خالی مثال قبل را با موارد زیر پر کنید:

{
  pageSize: 1,
  fields: '*',
}

البته انجام چنین کاری برای خروجی نهایی بهینه نخواهد بود چرا که لیست بزرگی از فیلدها را برای شما برمی‌گرداند. برای اینکه کارایی اپلیکیشن را بالا ببرید بهتر است به صورت منحصر به فرد نوع فیلد را مشخص کنید. 

 

fields: 'files(name, webViewLink)',

دسترسی به نتایج

اگر قصد نمایش خروجی‌های متد drive.files.list را داشته باشیم می‌توانیم از یک تابع callback استفاده کنیم. اما انجام این کار کمی پیچیده خواهد بود به همین دلیل بهتر است تا از async/await کمک بگیریم. یک مثال از این حالت را می‌توانید در زیر مشاهده کنید:

(async function () {
  let res = await drive.files.list({
    pageSize: 5,
    fields: 'files(name, webViewLink)',
    orderBy: 'createdTime desc'
  });
  console.log(res.data);
})()

ذخیره در یک فایل

برای ذخیره داده‌ها به صورت محلی بهترین روش استفاده از فرمت CSV است. برای اینکار ابتدا باید ماژول fs را وارد پروژه کنیم. 

بعد از این کار می‌توانیم از طریق fs.writeFile یک فایل را به صورت محلی ایجاد نماییم:

(async function () {
  let res = await new Promise((resolve, reject) => {
    drive.files.list({
      pageSize: 5,
      fields: 'files(name, webViewLink)',
      orderBy: 'createdTime desc'
    }, function (err, res) {
      if (err) {
        reject(err);
      }
        resolve(res);
    });
  });
  console.log(res.data);
})()

اگر قصد دسترسی به آخرین نسخه از فایل index.js تا به اینجای آموزش را دارید می‌توانید از این لینک استفاده کنید.

انتقال داده‌ها به Google Sheets

بعد از ذخیره اطلاعات به صورت محلی شاید بد نباشد اگر آن‌ها را در Google Sheets نیز ذخیره کنیم. برای اینکار ابتدا sheets را وارد پروژه کنید:

const drive = google.drive({ version: 'v3', auth });
const sheets = google.sheets({ version: 'v4', auth });

قصد داریم تا ادامه برنامه را نیز در همان تابع غیرهمزمان بنویسیم و امیدواریم که با ارائه چندین متد و مثال مختلف به خوبی بتوانید با کارکرد و ساختار کلی APIهای گوگل آشنایی پیدا کنید.

ایجاد یک Spreadsheet جدید

let newSheet = await sheets.spreadsheets.create({
  resource: {
    properties: {
      title: 'A new day, a new sheet',
    }
  }
});

انتقال Spreadsheet

یک فولدر جدید درست کرده و از طریق url آن به id فولدر دسترسی پیدا کنید. 

const updatedSheet = await drive.files.update({
  fileId: newSheet.data.spreadsheetId,
  addParents: directory,
  fields: 'id, parents'
});

انتقال مالکیت

به صورت پیشفرض اکانت سرویس مالک تمام فایل‌هایی خواهد بود که به این طریق ایجاد می‌شوند. البته با وجود اینکه چنین حالتی اشکالی بوجود نخواهد آورد اما اگر بخواهید این مالکیت را انتقال دهید می‌توانید به صورت زیر عمل نمایید:

await drive.permissions.create({
  fileId: newSheet.data.spreadsheetId,
  transferOwnership: 'true',
  resource: {
    role: 'owner',
    type: 'user',
    emailAddress: 'youremail@gmail.com'
  }
});

افزودن ردیف جدید

بعد از ایجاد و انتقال مالکیت فایل صفحه گسترده حال نیاز است که آن را با اطلاعات متد list پر کنیم. برای افزودن داده جدید می‌توان از متد sheets.spreadsheets.values.append استفاده کرد.

البته برای تمرین می‌توان ابتدا یکسری داده‌های دیگر را وارد کنیم تا از کارکرد درست آن متوجه شویم.

let sheetData = [['File Name', 'URL']];
res.data.files.map(entry => {
  const { name, webViewLink } = entry;
  sheetData.push([name, webViewLink]);
});
sheets.spreadsheets.values.append({
  spreadsheetId: newSheet.data.spreadsheetId,
  valueInputOption: 'USER_ENTERED',
  range: 'A1',
  resource: {
    range: 'A1',
    majorDimension: 'ROWS',
    values: sheetData,
  },
});

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

با استفاده از خصوصیات مختلف متد sheets.spreadsheets.batchUpdate می‌توانیم کارهای متفاوتی را با ردیف‌های صفحه گسترده انجام دهیم. در این مثال قصد داریم تا پس زمینه اولین ردیف را با رنگ سیاه و متن اولین ردیف را با رنگ سفید و حالت بولد نمایش دهیم:

await sheets.spreadsheets.batchUpdate({
  spreadsheetId: newSheet.data.spreadsheetId,
  resource: {
    requests: [
      {
        repeatCell: {
          range: {
            startRowIndex: 0,
            endRowIndex: 1
          },
          cell: {
            userEnteredFormat: {
              backgroundColor: {
                red: 0.2,
                green: 0.2,
                blue: 0.2
              },
              textFormat: {
                foregroundColor: {
                  red: 1,
                  green: 1,
                  blue: 1
                },
                bold: true,
              }
            }
          },
          fields: 'userEnteredFormat(backgroundColor,textFormat)'
        }
      },
    ]
  }
});

اگر قصد دسترسی به آخرین نسخه از فایل index.js می‌توانید از این لینک استفاده کنید.

در پایان

در این مطلب سعی داشتیم تا شما را با APIهای گوگل و شیوه استفاده از آن‌ها در نودجی‌اس و جاوااسکریپت آشنا کنیم. البته باید گفت که APIهای گوگل بسیار وسیع‌تر از این مطلب و مثال‌های آورده شده هستند، به همین دلیل نیاز است که مستندات آن را به خوبی مطالعه کنید. 

منبع

مقالات پیشنهادی

  • ایجاد یک Web Scraper با استفاده از جاوااسکریپت

    اگر قصد جمع‌آوری اطلاعات از دنیای وب را داشته باشید، منابع و ابزارهای بسیاری در اختیار شما قرار خواهد گرفت. زبان‌های برنامه‌نویسی مانند پایتون و PHP ت...

    ارسطو عباسی
  • شیوه استفاده از Arrow Function در جاوااسکریپت

    توابع Arrow نسبتا شیوه‌ای جدید برای تعریف توابع در جاوااسکریپت هستند. این ویژگی‌ بعد از معرفی ES6 در اختیار توسعه‌دهندگان قرار گرفت و براساس آمارها با...

    ارسطو عباسی