با افزونه‌های Google Workspace، ایمیل را کاربردی‌تر کنید

1. بررسی اجمالی

در این لبه کد، از Google Apps Script برای نوشتن یک افزونه Google Workspace برای Gmail استفاده خواهید کرد که به کاربران امکان می دهد داده های رسید را از یک ایمیل به صفحه گسترده مستقیماً در Gmail اضافه کنند. هنگامی که یک کاربر رسیدی را از طریق ایمیل دریافت می کند، افزونه را باز می کند که به طور خودکار اطلاعات مربوط به هزینه را از ایمیل دریافت می کند. کاربر می تواند اطلاعات هزینه را ویرایش کند و سپس آن را برای ثبت هزینه خود در صفحه گسترده Google Sheets ارسال کند.

چیزی که یاد خواهید گرفت

  • با استفاده از Google Apps Script یک افزونه Google Workspace برای Gmail ایجاد کنید
  • یک ایمیل را با Google Apps Script تجزیه کنید
  • از طریق Google Apps Script با Google Sheets تعامل داشته باشید
  • مقادیر کاربر را با استفاده از سرویس Properties Google Apps Script ذخیره کنید

آنچه شما نیاز دارید

  • دسترسی به اینترنت و مرورگر وب
  • یک اکانت گوگل
  • برخی از پیام‌ها، ترجیحاً رسیدهای ایمیل، در Gmail

2. کد نمونه را دریافت کنید

همانطور که از طریق این کد لبه کار می کنید، ممکن است ارجاع به نسخه فعال کدی که می نویسید مفید باشد. مخزن GitHub حاوی کد نمونه ای است که می توانید از آن به عنوان مرجع استفاده کنید.

برای دریافت کد نمونه، از خط فرمان، اجرا کنید:

git clone https://github.com/googleworkspace/gmail-add-on-codelab.git

3. یک افزونه اساسی بسازید

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

ابتدا یک پروژه Apps Script جدید ایجاد کنید و فایل مانیفست آن را باز کنید.

  1. به script.google.com بروید. از اینجا می‌توانید پروژه‌های Apps Script خود را ایجاد، مدیریت و نظارت کنید.
  2. برای ایجاد یک پروژه جدید، در بالا سمت چپ، روی پروژه جدید کلیک کنید. پروژه جدید با یک فایل پیش فرض به نام Code.gs باز می شود. فعلا Code.gs به حال خود رها کنید، بعداً با آن کار خواهید کرد.
  3. روی پروژه Untitled کلیک کنید، نام پروژه خود را Expense It! و روی تغییر نام کلیک کنید.
  4. در سمت چپ، روی تنظیمات پروژه کلیک کنید تنظیمات پروژه .
  5. کادر بررسی نمایش فایل مانیفست "appscript.json" در ویرایشگر" را انتخاب کنید.
  6. روی ویرایشگر کلیک کنید ویرایشگر .
  7. برای باز کردن فایل مانیفست، در سمت چپ، روی appscript.json کلیک کنید.

در appscript.json ، فراداده مرتبط با افزونه را مشخص کنید، مانند نام آن و مجوزهای مورد نیاز آن. این تنظیمات پیکربندی را جایگزین محتویات appsscript.json کنید:

{
  "timeZone": "GMT",
  "oauthScopes": [
    "https://www.googleapis.com/auth/gmail.addons.execute"
  ],
  "gmail": {
    "name": "Expense It!",
    "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/receipt_black_24dp.png",
    "contextualTriggers": [{
      "unconditional": {
      },
      "onTriggerFunction": "getContextualAddOn"
    }],
    "primaryColor": "#41f470",
    "secondaryColor": "#94f441"
  }
}

به بخشی از مانیفست به نام contextualTriggers توجه ویژه ای داشته باشید. این قسمت از مانیفست عملکرد تعریف شده توسط کاربر را برای فراخوانی در اولین فعال شدن افزونه شناسایی می کند. در این مورد، getContextualAddOn را فراخوانی می کند که جزئیات ایمیل باز را دریافت می کند و مجموعه ای از کارت ها را برای نمایش به کاربر برمی گرداند.

برای ایجاد تابع getContextualAddOn ، مراحل زیر را دنبال کنید:

  1. در سمت چپ، نشانگر را روی Code.gs نگه دارید، سپس روی Menu کلیک کنید منوی بیشتر > تغییر نام .
  2. GetContextualAddOn را تایپ کرده و کلید Enter را فشار دهید. Apps Script به طور خودکار .gs را به نام فایل شما اضافه می کند، بنابراین نیازی به تایپ پسوند فایل ندارید. اگر GetContextualAddOn.gs را تایپ کنید، Apps Script فایل شما را GetContextualAddOn.gs.gs نامگذاری می کند.
  3. در GetContextualAddOn.gs ، کد پیش فرض را با تابع getContextualAddOn جایگزین کنید:
/**
 * Returns the contextual add-on data that should be rendered for
 * the current e-mail thread. This function satisfies the requirements of
 * an 'onTriggerFunction' and is specified in the add-on's manifest.
 *
 * @param {Object} event Event containing the message ID and other context.
 * @returns {Card[]}
 */
function getContextualAddOn(event) {
  var card = CardService.newCardBuilder();
  card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense'));

  var section = CardService.newCardSection();
  section.addWidget(CardService.newTextInput()
    .setFieldName('Date')
    .setTitle('Date'));
  section.addWidget(CardService.newTextInput()
    .setFieldName('Amount')
    .setTitle('Amount'));
  section.addWidget(CardService.newTextInput()
    .setFieldName('Description')
    .setTitle('Description'));
  section.addWidget(CardService.newTextInput()
    .setFieldName('Spreadsheet URL')
    .setTitle('Spreadsheet URL'));

  card.addSection(section);

  return [card.build()];
}

رابط کاربری هر افزونه Google Workspace از کارت هایی تشکیل شده است که به یک یا چند بخش تقسیم می شوند که هر بخش شامل ویجت هایی است که می تواند اطلاعات کاربر را نمایش دهد و از او دریافت کند. تابع getContextualAddOn یک کارت واحد ایجاد می کند که جزئیات مربوط به هزینه های موجود در ایمیل را دریافت می کند. کارت دارای یک بخش است که شامل فیلدهای ورودی متن برای داده های مربوطه است. تابع آرایه ای از کارت های افزونه را برمی گرداند. در این مورد، آرایه برگشتی فقط شامل یک کارت است.

قبل از استقرار Expense It! افزونه، به یک پروژه Google Cloud Platform (GCP) نیاز دارید که پروژه‌های Apps Script از آن برای مدیریت مجوزها، خدمات پیشرفته و سایر جزئیات استفاده می‌کنند. برای کسب اطلاعات بیشتر، از Google Cloud Platform Projects دیدن کنید.

برای استقرار و اجرای افزونه خود، این مراحل را دنبال کنید:

  1. پروژه GCP خود را باز کنید و شماره پروژه آن را کپی کنید .
  2. از پروژه Apps Script خود، در سمت چپ، روی تنظیمات پروژه کلیک کنید تنظیمات پروژه .
  3. در بخش «پروژه Google Cloud Platform (GCP)»، روی تغییر پروژه کلیک کنید.
  4. شماره پروژه پروژه GCP خود را وارد کنید، سپس روی تنظیم پروژه کلیک کنید.
  5. روی Deploy > Test Deployments کلیک کنید.
  6. مطمئن شوید که نوع استقرار افزونه Google Workspace است. در صورت لزوم، در بالای کادر گفتگو، روی فعال کردن انواع استقرار کلیک کنید انواع استقرار را فعال کنید و Google Workspace Add-on را به عنوان نوع استقرار انتخاب کنید.
  7. در کنار برنامه(ها): Gmail ، روی Install کلیک کنید.
  8. روی Done کلیک کنید.

اکنون می توانید افزونه را در صندوق ورودی جیمیل خود مشاهده کنید.

  1. در رایانه، Gmail را باز کنید.
  2. در پانل سمت راست، Expense It! خرج کن! نماد رسید افزودنی ظاهر می شود. ممکن است لازم باشد روی More Add-ons کلیک کنید افزونه های بیشتر برای پیدا کردن آن
  3. یک ایمیل، ترجیحا رسید با هزینه ها باز کنید.
  4. برای باز کردن افزونه، در پنل سمت راست، روی Expense It کلیک کنید! خرج کن! نماد رسید .
  5. خرجش را بده! با کلیک کردن روی مجوز دسترسی به حساب Google خود دسترسی داشته باشید و دستورات را دنبال کنید.

این افزونه یک فرم ساده را در کنار یک پیام باز Gmail نشان می دهد. هنوز کار دیگری انجام نمی دهد، اما عملکرد آن را در بخش بعدی خواهید دید.

برای مشاهده به‌روزرسانی‌های برافزای خود در حین ادامه در این آزمایشگاه، فقط باید کد خود را ذخیره کنید و Gmail را بازخوانی کنید. هیچ استقرار اضافی مورد نیاز نیست.

4. دسترسی به پیام های ایمیل

کدی را اضافه کنید که محتوای ایمیل را دریافت کند و کد را برای سازماندهی بیشتر مدولار کنید.

در کنار Files روی Add کلیک کنید یک فایل اضافه کنید > فایلی به نام Cards اسکریپت و ایجاد کنید. یک فایل اسکریپت دوم به نام Helpers ایجاد کنید. Cards.gs کارت را ایجاد می کند و از توابع Helpers.gs برای پر کردن فیلدها در فرم بر اساس محتوای ایمیل استفاده می کند.

کد پیش‌فرض در Cards.gs را با این کد جایگزین کنید:

var FIELDNAMES = ['Date', 'Amount', 'Description', 'Spreadsheet URL'];

/**
 * Creates the main card users see with form inputs to log expenses.
 * Form can be prefilled with values.
 *
 * @param {String[]} opt_prefills Default values for each input field.
 * @param {String} opt_status Optional status displayed at top of card.
 * @returns {Card}
 */
function createExpensesCard(opt_prefills, opt_status) {
  var card = CardService.newCardBuilder();
  card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense'));
  
  if (opt_status) {
    if (opt_status.indexOf('Error: ') == 0) {
      opt_status = '<font color=\'#FF0000\'>' + opt_status + '</font>';
    } else {
      opt_status = '<font color=\'#228B22\'>' + opt_status + '</font>';
    }
    var statusSection = CardService.newCardSection();
    statusSection.addWidget(CardService.newTextParagraph()
      .setText('<b>' + opt_status + '</b>'));
    card.addSection(statusSection);
  }
  
  var formSection = createFormSection(CardService.newCardSection(),
                                      FIELDNAMES, opt_prefills);
  card.addSection(formSection);
  
  return card;
}

/**
 * Creates form section to be displayed on card.
 *
 * @param {CardSection} section The card section to which form items are added.
 * @param {String[]} inputNames Names of titles for each input field.
 * @param {String[]} opt_prefills Default values for each input field.
 * @returns {CardSection}
 */
function createFormSection(section, inputNames, opt_prefills) {
  for (var i = 0; i < inputNames.length; i++) {
    var widget = CardService.newTextInput()
      .setFieldName(inputNames[i])
      .setTitle(inputNames[i]);
    if (opt_prefills && opt_prefills[i]) {
      widget.setValue(opt_prefills[i]);
    }
    section.addWidget(widget);
  }
  return section;
}

تابع createExpensesCard آرایه ای از مقادیر را می گیرد تا فرم را به عنوان یک آرگومان اختیاری از قبل پر کند. این تابع می تواند یک پیام وضعیت اختیاری را نمایش دهد که اگر وضعیت با "خطا:" شروع شود قرمز رنگ می شود و در غیر این صورت سبز است. به جای افزودن دستی هر فیلد به فرم، یک تابع کمکی به نام createFormSection در فرآیند ایجاد ابزارک های ورودی متن حلقه می زند، هر مقدار پیش فرض را با setValue تنظیم می کند و سپس ویجت ها را به بخش های مربوطه روی کارت اضافه می کند.

اکنون کد پیش‌فرض Helpers.gs را با این کد جایگزین کنید:

/**
 * Finds largest dollar amount from email body.
 * Returns null if no dollar amount is found.
 *
 * @param {Message} message An email message.
 * @returns {String}
 */
function getLargestAmount(message) {
  return 'TODO';
}

/**
 * Determines date the email was received.
 *
 * @param {Message} message An email message.
 * @returns {String}
 */
function getReceivedDate(message) {
  return 'TODO';
}

/**
 * Determines expense description by joining sender name and message subject.
 *
 * @param {Message} message An email message.
 * @returns {String}
 */
function getExpenseDescription(message) {
  return 'TODO';
}

/**
 * Determines most recent spreadsheet URL.
 * Returns null if no URL was previously submitted.
 *
 * @returns {String}
 */
function getSheetUrl() {
  return 'TODO';
}

توابع در Helpers.gs توسط getContextualAddon فراخوانی می شوند تا مقادیر از پیش پر شده در فرم را تعیین کنند. در حال حاضر، این توابع فقط رشته "TODO" را برمی گردانند زیرا منطق prefill را در مرحله بعدی پیاده سازی خواهید کرد.

سپس، کد را در GetContextualAddon.gs به‌روزرسانی کنید تا از کد موجود در Cards.gs و Helpers.gs استفاده کند. کد موجود در GetContextualAddon.gs را با این کد جایگزین کنید:

/**
 * Copyright 2017 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * Returns the contextual add-on data that should be rendered for
 * the current e-mail thread. This function satisfies the requirements of
 * an 'onTriggerFunction' and is specified in the add-on's manifest.
 *
 * @param {Object} event Event containing the message ID and other context.
 * @returns {Card[]}
 */
function getContextualAddOn(event) {
  var message = getCurrentMessage(event);
  var prefills = [getReceivedDate(message),
                  getLargestAmount(message),
                  getExpenseDescription(message),
                  getSheetUrl()];
  var card = createExpensesCard(prefills);

  return [card.build()];
}

/**
 * Retrieves the current message given an action event object.
 * @param {Event} event Action event object
 * @return {Message}
 */
function getCurrentMessage(event) {
  var accessToken = event.messageMetadata.accessToken;
  var messageId = event.messageMetadata.messageId;
  GmailApp.setCurrentMessageAccessToken(accessToken);
  return GmailApp.getMessageById(messageId);
}

به تابع جدید getCurrentMessage توجه کنید که از رویداد ارائه شده توسط Gmail برای خواندن پیام باز شده کاربر استفاده می کند. برای اینکه این عملکرد کار کند، یک محدوده اضافی به مانیفست اسکریپت اضافه کنید که امکان دسترسی فقط خواندنی به پیام‌های Gmail را فراهم می‌کند.

در appscript.json ، oauthScopes به‌روزرسانی کنید تا محدوده https://www.googleapis.com/auth/gmail.addons.current.message.readonly را نیز درخواست کند.

"oauthScopes": [
  "https://www.googleapis.com/auth/gmail.addons.execute",
   "https://www.googleapis.com/auth/gmail.addons.current.message.readonly"
],

در Gmail، افزونه خود را اجرا کنید و اجازه دسترسی برای Expense It را بدهید! برای مشاهده پیام های ایمیل فیلدهای فرم اکنون با "TODO" از قبل پر شده اند.

5. با Google Sheets تعامل داشته باشید

هزینه آن! افزونه فرمی دارد که کاربر می‌تواند جزئیات مربوط به هزینه را وارد کند، اما این جزئیات جایی برای رفتن ندارند. بیایید دکمه ای اضافه کنیم که داده های فرم را به یک برگه Google ارسال می کند.

برای افزودن یک دکمه، از کلاس ButtonSet استفاده می کنیم. برای ارتباط با Google Sheets، از سرویس Google Sheets استفاده خواهیم کرد.

createFormSection تغییر دهید تا دکمه ای با عنوان "ارسال" را به عنوان بخشی از بخش فرم کارت برگردانید. مراحل زیر را انجام دهید:

  1. یک دکمه متنی با استفاده از CardService.newTextButton() ایجاد کنید و با استفاده از CardService.TextButton.setText() روی دکمه "Submit" برچسب بزنید.
  2. دکمه را طوری طراحی کنید که وقتی روی آن کلیک می‌شود، عمل submitForm زیر از طریق CardService.TextButton.setOnClickAction() فراخوانی شود:
/**
 * Logs form inputs into a spreadsheet given by URL from form.
 * Then displays edit card.
 *
 * @param {Event} e An event object containing form inputs and parameters.
 * @returns {Card}
 */
function submitForm(e) {
  var res = e['formInput'];
  try {
    FIELDNAMES.forEach(function(fieldName) {
      if (! res[fieldName]) {
        throw 'incomplete form';
      }
    });
    var sheet = SpreadsheetApp
      .openByUrl((res['Spreadsheet URL']))
      .getActiveSheet();
    sheet.appendRow(objToArray(res, FIELDNAMES.slice(0, FIELDNAMES.length - 1)));
    return createExpensesCard(null, 'Logged expense successfully!').build();
  }
  catch (err) {
    if (err == 'Exception: Invalid argument: url') {
      err = 'Invalid URL';
      res['Spreadsheet URL'] = null;
    }
    return createExpensesCard(objToArray(res, FIELDNAMES), 'Error: ' + err).build();
  }
}

/**
 * Returns an array corresponding to the given object and desired ordering of keys.
 *
 * @param {Object} obj Object whose values will be returned as an array.
 * @param {String[]} keys An array of key names in the desired order.
 * @returns {Object[]}
 */
function objToArray(obj, keys) {
  return keys.map(function(key) {
    return obj[key];
  });
}
  1. با استفاده از CardService.newButtonSet() یک ویجت مجموعه دکمه ایجاد کنید و دکمه متن خود را به دکمه تنظیم شده با CardService.ButtonSet.addButton() اضافه کنید.
  2. ویجت مجموعه دکمه را با استفاده از CardService.CardSection.addWidget() به بخش فرم کارت اضافه کنید.

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

در نهایت، بخش oauthScopes را در appsscript.json به‌روزرسانی کنید و دوباره دامنه را درخواست کنید https://www.googleapis.com/auth/spreadsheets . هنگامی که مجاز باشد، این محدوده به افزونه اجازه می‌دهد کاربرگ‌نگار Google کاربر را بخواند و تغییر دهد.

"oauthScopes": [
  "https://www.googleapis.com/auth/gmail.addons.execute",
  "https://www.googleapis.com/auth/gmail.addons.current.message.readonly",
  "https://www.googleapis.com/auth/spreadsheets"
],

اگر قبلاً صفحه‌گسترده جدیدی ایجاد نکرده‌اید، در https://docs.google.com/spreadsheets/ ایجاد کنید.

حالا افزونه را دوباره اجرا کنید و سعی کنید فرم را ارسال کنید. اطمینان حاصل کنید که URL کامل URL مقصد خود را در قسمت فرم URL صفحه گسترده وارد کرده اید.

6. مقادیر را با سرویس Properties ذخیره کنید

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

سرویس Properties به ما امکان می دهد جفت های کلید-مقدار را ذخیره کنیم . در مورد ما، یک کلید معقول "SPREADSHEET_URL" خواهد بود در حالی که مقدار خود URL است. برای ذخیره چنین مقداری، باید submitForm در Cards.gs تغییر دهید تا URL صفحه گسترده با افزودن یک ردیف جدید به برگه به ​​عنوان یک ویژگی ذخیره شود.

توجه داشته باشید که ویژگی ها می توانند یکی از سه حوزه را داشته باشند: اسکریپت، کاربر یا سند . دامنه سند برای افزونه‌های Gmail اعمال نمی‌شود، اگرچه در هنگام ذخیره اطلاعات خاص یک سند یا برگه Google خاص، به نوع جداگانه‌ای از برافزا مربوط می‌شود. برای افزونه ما، رفتار مطلوب این است که یک فرد آخرین صفحه گسترده خود (برخلاف دیگران) را به عنوان گزینه پیش‌فرض در فرم ببیند. در نتیجه، به جای محدوده اسکریپت ، محدوده کاربری را انتخاب می کنیم.

از PropertiesService.getUserProperties().setProperty() برای ذخیره URL صفحه گسترده استفاده کنید. موارد زیر را به submitForm در Cards.gs اضافه کنید:

PropertiesService.getUserProperties().setProperty('SPREADSHEET_URL', 
    res['Spreadsheet URL']);

سپس تابع getSheetUrl را در Helpers.gs تغییر دهید تا ویژگی ذخیره شده را برگرداند تا کاربر هر بار که از افزونه استفاده می کند آخرین URL را ببیند. برای دریافت مقدار ویژگی از PropertiesService.getUserProperties().getProperty() استفاده کنید.

/**
 * Determines most recent spreadsheet URL.
 * Returns null if no URL was previously submitted.
 *
 * @returns {String}
 */
function getSheetUrl() {
  return PropertiesService.getUserProperties().getProperty('SPREADSHEET_URL');
}

در نهایت، برای دسترسی به سرویس Property، اسکریپت نیز باید مجوز داشته باشد. محدوده https://www.googleapis.com/auth/script.storage را مانند قبل به مانیفست اضافه کنید تا به افزونه شما اجازه دهید اطلاعات دارایی را بخواند و بنویسد.

7. پیام جیمیل را تجزیه کنید

برای اینکه واقعاً در وقت کاربران صرفه جویی کنیم، بیایید فرم را با اطلاعات مربوط به هزینه ایمیل از قبل پر کنیم. ما قبلاً توابعی را در Helpers.gs ایجاد کرده‌ایم که این نقش را بازی می‌کنند، اما تاکنون فقط "TODO" را برای تاریخ، مبلغ و شرح هزینه برگردانده‌ایم.

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

/**
 * Determines date the email was received.
 *
 * @param {Message} message - The message currently open.
 * @returns {String}
 */
function getReceivedDate(message) {
  return message.getDate().toLocaleDateString();
}

دو تابع باقی مانده را اجرا کنید:

  1. getExpenseDescription ممکن است مستلزم پیوستن به نام فرستنده و موضوع پیام باشد، اگرچه راه‌های پیچیده‌تری برای تجزیه متن پیام و ارائه توضیحات دقیق‌تر وجود دارد.
  2. برای getLargestAmount به دنبال نمادهای خاص مرتبط با پول باشید. رسیدها اغلب دارای مقادیر متعددی مانند مالیات و سایر هزینه ها هستند. به این فکر کنید که چگونه می توانید مقدار صحیح را تشخیص دهید. عبارات منظم نیز ممکن است مفید باشند.

اگر به الهام بیشتری نیاز دارید، مستندات مرجع GmailMessage را کاوش کنید یا کد راه حلی را که در ابتدای برنامه کد دانلود کرده اید بررسی کنید. هنگامی که پیاده سازی های خود را برای همه توابع در Helpers.gs ابداع کردید، افزونه خود را برای یک چرخش انتخاب کنید! رسیدها را باز کنید و شروع به ثبت آنها در صفحه گسترده کنید!

8. فرم را با اقدامات کارت پاک کنید

چه اتفاقی می افتد اگر آن را خرج کنید! هزینه ای را در یک ایمیل باز شناسایی اشتباه می کند و فرم را با اطلاعات نادرست از قبل پر می کند؟ کاربر فرم را پاک می کند. کلاس CardAction به ما این امکان را می دهد که تابعی را مشخص کنیم که با کلیک روی عملکرد فراخوانی شود. بیایید از آن استفاده کنیم تا به کاربر راهی سریع برای پاک کردن فرم بدهیم.

createExpensesCard طوری تغییر دهید که کارتی که برمی گرداند دارای یک عملکرد کارت با عنوان "Clear form" باشد و وقتی روی آن کلیک کرد تابع clearForm زیر را فراخوانی کند که می توانید آن را در Cards.gs جایگذاری کنید. باید opt_status را به عنوان پارامتری به نام "Status" به اکشن ارسال کنید تا اطمینان حاصل کنید که وقتی فرم پاک می شود، پیام وضعیت باقی می ماند. توجه داشته باشید که پارامترهای اختیاری برای اقدامات باید از نوع Object باشند.<string, string>، بنابراین اگر opt_status در دسترس نیست، باید {'Status' : ''} را ارسال کنید.

/**
 * Recreates the main card without prefilled data.
 *
 * @param {Event} e An event object containing form inputs and parameters.
 * @returns {Card}
 */
function clearForm(e) {
  return createExpensesCard(null, e['parameters']['Status']).build();
}

9. یک صفحه گسترده ایجاد کنید

فراتر از استفاده از Google Apps Script برای ویرایش یک صفحه گسترده موجود، می توانید یک صفحه گسترده کاملاً جدید را به صورت برنامه ریزی شده ایجاد کنید. برای افزودنی ما، اجازه دهید کاربر بتواند یک صفحه گسترده برای هزینه ها ایجاد کند. برای شروع، بخش کارت زیر را به کارتی که createExpensesCard برمی گرداند اضافه کنید.

var newSheetSection = CardService.newCardSection();
var sheetName = CardService.newTextInput()
  .setFieldName('Sheet Name')
  .setTitle('Sheet Name');
var createExpensesSheet = CardService.newAction()
  .setFunctionName('createExpensesSheet');
var newSheetButton = CardService.newTextButton()
  .setText('New Sheet')
  .setOnClickAction(createExpensesSheet);
newSheetSection.addWidget(sheetName);
newSheetSection.addWidget(CardService.newButtonSet().addButton(newSheetButton));
card.addSection(newSheetSection);

اکنون، هنگامی که کاربر روی دکمه "صفحه جدید" کلیک می کند، افزونه صفحه گسترده جدیدی ایجاد می کند که با یک ردیف سرصفحه فرمت شده است که به گونه ای ثابت است که همیشه قابل مشاهده باشد. کاربر عنوانی را برای صفحه‌گسترده جدید در فرم مشخص می‌کند، اگرچه گنجاندن یک مقدار پیش‌فرض در صورت خالی بودن فرم ممکن است انتخاب خوبی باشد. در اجرای createExpensesSheet ، یک کارت تقریباً یکسان را با اضافه کردن یک پیام وضعیت مناسب و همچنین پر کردن فیلد URL با URL صفحه گسترده جدید، به کارت موجود برگردانید.

10. تبریک می گویم!

شما با موفقیت یک افزونه Gmail را طراحی و پیاده‌سازی کرده‌اید که هزینه‌ای را در ایمیل پیدا می‌کند و به کاربران کمک می‌کند هزینه‌ها را در یک صفحه گسترده فقط در چند ثانیه ثبت کنند. شما از اسکریپت Google Apps برای ارتباط با چندین API Google و داده‌های پایدار بین چندین اجرای افزونه استفاده کرده‌اید.

بهبودهای احتمالی

اجازه دهید تخیلتان شما را راهنمایی کند که هزینه آن را افزایش می دهید، اما در اینجا چند ایده برای ساختن یک محصول مفیدتر وجود دارد:

  • هنگامی که کاربر هزینه ای را ثبت کرد، به صفحه گسترده پیوند دهید
  • قابلیت ویرایش/لغو ثبت هزینه را اضافه کنید
  • APIهای خارجی را ادغام کنید تا به کاربران امکان پرداخت و درخواست پول را بدهید

بیشتر بدانید