Google Workspace অ্যাড-অন ব্যবহার করে ইমেলকে আরও কার্যকর করুন

১. সংক্ষিপ্ত বিবরণ

এই কোডল্যাবে, আপনি গুগল অ্যাপস স্ক্রিপ্ট ব্যবহার করে জিমেইলের জন্য একটি গুগল ওয়ার্কস্পেস অ্যাড-অন লিখবেন, যা ব্যবহারকারীদের ইমেইল থেকে রসিদের ডেটা সরাসরি জিমেইলের মধ্যেই একটি স্প্রেডশিটে যোগ করার সুযোগ দেবে। যখন কোনো ব্যবহারকারী ইমেইলে একটি রসিদ পান, তখন তিনি অ্যাড-অনটি খোলেন, যা স্বয়ংক্রিয়ভাবে ইমেইল থেকে প্রাসঙ্গিক খরচের তথ্য সংগ্রহ করে নেয়। ব্যবহারকারী খরচের তথ্য সম্পাদনা করতে পারেন এবং তারপর তাদের খরচ একটি গুগল শিটস স্প্রেডশিটে নথিভুক্ত করার জন্য তা জমা দিতে পারেন।

আপনি যা শিখবেন

  • গুগল অ্যাপস স্ক্রিপ্ট ব্যবহার করে জিমেইলের জন্য একটি গুগল ওয়ার্কস্পেস অ্যাড-অন তৈরি করুন।
  • গুগল অ্যাপস স্ক্রিপ্ট দিয়ে একটি ইমেল পার্স করুন
  • গুগল অ্যাপস স্ক্রিপ্টের মাধ্যমে গুগল শিটস-এর সাথে ইন্টারঅ্যাক্ট করুন
  • গুগল অ্যাপস স্ক্রিপ্টের প্রোপার্টিজ সার্ভিস ব্যবহার করে ব্যবহারকারীর মান সংরক্ষণ করুন।

আপনার যা যা লাগবে

  • ইন্টারনেট এবং একটি ওয়েব ব্রাউজারে প্রবেশাধিকার
  • একটি গুগল অ্যাকাউন্ট
  • জিমেইলে কিছু বার্তা, বিশেষ করে ইমেইল প্রাপ্তি স্বীকারপত্র।

২. নমুনা কোডটি নিন।

এই কোডল্যাবটি করার সময়, আপনার লেখা কোডের একটি কার্যকরী সংস্করণ দেখে নিলে তা সহায়ক হতে পারে। গিটহাব রিপোজিটরিতে নমুনা কোড রয়েছে যা আপনি রেফারেন্স হিসেবে ব্যবহার করতে পারেন।

নমুনা কোডটি পেতে, কমান্ড লাইন থেকে চালান:

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

৩. একটি বেসিক অ্যাড-অন তৈরি করুন

প্রথমে অ্যাড-অনটির একটি সরল সংস্করণের জন্য কোড লিখুন, যা ইমেইলের পাশাপাশি একটি খরচের ফর্ম প্রদর্শন করবে।

প্রথমে, একটি নতুন অ্যাপস স্ক্রিপ্ট প্রজেক্ট তৈরি করুন এবং এর ম্যানিফেস্ট ফাইলটি খুলুন।

  1. script.google.com- এ যান। এখান থেকে আপনি আপনার অ্যাপস স্ক্রিপ্ট প্রজেক্টগুলো তৈরি, পরিচালনা এবং পর্যবেক্ষণ করতে পারবেন।
  2. একটি নতুন প্রজেক্ট তৈরি করতে, উপরের বাম দিকে 'New Project'-এ ক্লিক করুন। নতুন প্রজেক্টটি Code.gs নামের একটি ডিফল্ট ফাইলসহ খুলবে। আপাতত Code.gs অপরিবর্তিত রাখুন, আপনি এটি নিয়ে পরে কাজ করবেন।
  3. Untitled project-এ ক্লিক করুন, আপনার প্রজেক্টের নাম দিন Expense It!, এবং Rename-এ ক্লিক করুন।
  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 এর উপর পয়েন্টারটি ধরে রাখুন, তারপর মেনুতে ক্লিক করুন। আরও মেনু নাম পরিবর্তন করুন
  2. GetContextualAddOn টাইপ করুন এবং Enter কী চাপুন। অ্যাপস স্ক্রিপ্ট স্বয়ংক্রিয়ভাবে আপনার ফাইলের নামের শেষে .gs যুক্ত করে দেয়, তাই আপনাকে কোনো ফাইল এক্সটেনশন টাইপ করতে হবে না। আপনি যদি GetContextualAddOn.gs টাইপ করেন, তাহলে অ্যাপস স্ক্রিপ্ট আপনার ফাইলের নাম দেবে 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()];
}

প্রতিটি গুগল ওয়ার্কস্পেস অ্যাড-অনের ইউজার ইন্টারফেস এক বা একাধিক বিভাগে বিভক্ত কার্ড নিয়ে গঠিত, যার প্রতিটিতে এমন উইজেট থাকে যা ব্যবহারকারীর কাছ থেকে তথ্য প্রদর্শন ও গ্রহণ করতে পারে। getContextualAddOn ফাংশনটি একটি একক কার্ড তৈরি করে যা একটি ইমেইলে পাওয়া খরচের বিবরণ সংগ্রহ করে। কার্ডটিতে প্রাসঙ্গিক ডেটার জন্য টেক্সট ইনপুট ফিল্ডসহ একটি বিভাগ রয়েছে। ফাংশনটি অ্যাড-অনের কার্ডগুলোর একটি অ্যারে রিটার্ন করে। এক্ষেত্রে, রিটার্ন করা অ্যারেতে কেবল একটি কার্ড অন্তর্ভুক্ত থাকে।

Expense It! অ্যাড-অনটি স্থাপন করার আগে, আপনার একটি Google Cloud Platform (GCP) প্রজেক্ট প্রয়োজন, যা Apps Script প্রজেক্টগুলো অনুমোদন, উন্নত পরিষেবা এবং অন্যান্য বিবরণ পরিচালনা করতে ব্যবহার করে। আরও জানতে, Google Cloud Platform Projects দেখুন।

আপনার অ্যাড-অনটি স্থাপন ও চালু করতে, এই ধাপগুলো অনুসরণ করুন:

  1. আপনার GCP প্রজেক্টটি খুলুন এবং এর প্রজেক্ট নম্বরটি কপি করুন
  2. আপনার অ্যাপস স্ক্রিপ্ট প্রজেক্টের বাম দিকে, প্রজেক্ট সেটিংস-এ ক্লিক করুন। প্রকল্পের সেটিংস .
  3. ‘Google Cloud Platform (GCP) Project’-এর অধীনে, Change project-এ ক্লিক করুন।
  4. আপনার GCP প্রজেক্টের প্রজেক্ট নম্বরটি প্রবেশ করান, তারপর 'সেট প্রজেক্ট' বাটনে ক্লিক করুন।
  5. Deploy > Test deployments-এ ক্লিক করুন।
  6. নিশ্চিত করুন যে ডেপ্লয়মেন্ট টাইপটি ‘Google Workspace Add-on’ । প্রয়োজনে, ডায়ালগের শীর্ষে ‘Enable deployment types’-এ ক্লিক করুন। ডেপ্লয়মেন্ট প্রকারগুলি সক্ষম করুন এবং ডেপ্লয়মেন্ট টাইপ হিসেবে গুগল ওয়ার্কস্পেস অ্যাড-অন নির্বাচন করুন।
  7. Application(s): Gmail-এর পাশে, Install-এ ক্লিক করুন।
  8. সম্পন্ন ক্লিক করুন।

এখন আপনি আপনার জিমেইল ইনবক্সে অ্যাড-অনটি দেখতে পাবেন।

  1. আপনার কম্পিউটারে জিমেইল খুলুন।
  2. ডান পাশের প্যানেলে, এক্সপেন্স ইট! খরচ করুন! রসিদ আইকন অ্যাড-অনটি দেখা যাচ্ছে। আপনাকে আরও অ্যাড-অন-এ ক্লিক করতে হতে পারে। আরও অতিরিক্ত সংযোজন এটা খুঁজে বের করতে।
  3. একটি ইমেল খুলুন, বিশেষ করে খরচের রসিদটি।
  4. অ্যাড-অনটি খোলার জন্য, ডান পাশের প্যানেলে 'Expense It!'-এ ক্লিক করুন। খরচ করুন! রসিদ আইকন .
  5. Authorize Access-এ ক্লিক করে Expense It!-কে আপনার Google অ্যাকাউন্টে অ্যাক্সেস দিন এবং নির্দেশাবলী অনুসরণ করুন।

অ্যাড-অনটি একটি খোলা জিমেইল বার্তার পাশে একটি সাধারণ ফর্ম দেখায়। এটি এখনও অন্য কিছু করে না, তবে আপনি পরবর্তী বিভাগে এর কার্যকারিতা তৈরি করবেন।

এই ল্যাবটি সম্পন্ন করার সময় আপনার অ্যাড-অনের আপডেটগুলো দেখতে, আপনাকে শুধু আপনার কোড সেভ করে জিমেইল রিফ্রেশ করতে হবে। অতিরিক্ত কোনো ডেপ্লয়মেন্টের প্রয়োজন নেই।

৪. ইমেল বার্তা অ্যাক্সেস করুন

ইমেইলের বিষয়বস্তু সংগ্রহ করার জন্য কোড যোগ করুন এবং আরও কিছুটা গোছানোর জন্য কোডটিকে মডিউলারাইজ করুন।

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 ফাংশনটি ফর্মটি আগে থেকে পূরণ করার জন্য একটি ঐচ্ছিক আর্গুমেন্ট হিসেবে ভ্যালুগুলোর একটি অ্যারে গ্রহণ করে। ফাংশনটি একটি ঐচ্ছিক স্ট্যাটাস মেসেজ প্রদর্শন করতে পারে, যা স্ট্যাটাসটি "Error:" দিয়ে শুরু হলে লাল রঙের এবং অন্যথায় সবুজ রঙের হয়। ফর্মে প্রতিটি ফিল্ড ম্যানুয়ালি যোগ করার পরিবর্তে, 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';
}

ফর্মের আগে থেকে পূরণ করা মানগুলো নির্ধারণ করার জন্য getContextualAddon দ্বারা Helpers.gs এর ফাংশনগুলোকে কল করা হয়। আপাতত, এই ফাংশনগুলো শুধুমাত্র "TODO" স্ট্রিংটি রিটার্ন করবে, কারণ আপনি পরবর্তী ধাপে প্রিফিল লজিকটি প্রয়োগ করবেন।

এরপরে, 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 বার্তাগুলিতে শুধুমাত্র-পঠন (read-only) অ্যাক্সেসের অনুমতি দেয়।

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"
],

জিমেইলে, আপনার অ্যাড-অনটি চালান এবং ইমেল বার্তা দেখার জন্য Expense It!-কে অ্যাক্সেস অনুমোদন করুন। ফর্মের ফিল্ডগুলো এখন "TODO" দিয়ে আগে থেকেই পূরণ করা থাকবে।

৫. গুগল শিটসের সাথে ইন্টারঅ্যাক্ট করুন

Expense It! অ্যাড-অনটিতে ব্যবহারকারীর খরচের বিবরণ দেওয়ার জন্য একটি ফর্ম আছে, কিন্তু সেই বিবরণগুলো পাঠানোর কোনো জায়গা নেই। চলুন, এমন একটি বাটন যোগ করি যা ফর্মের ডেটা একটি গুগল শিটে পাঠিয়ে দেবে।

বাটন যোগ করতে আমরা ButtonSet ক্লাসটি ব্যবহার করব। গুগল শিটসের সাথে ইন্টারফেস করতে আমরা Google Sheets সার্ভিসটি ব্যবহার করব।

কার্ডের ফর্ম সেকশনের অংশ হিসেবে "Submit" লেবেলযুক্ত একটি বাটন রিটার্ন করার জন্য createFormSection পরিবর্তন করুন। নিম্নলিখিত ধাপগুলো অনুসরণ করুন:

  1. CardService.newTextButton() ব্যবহার করে একটি টেক্সট বাটন তৈরি করুন এবং CardService.TextButton.setText() ব্যবহার করে বাটনটিকে "Submit" লেবেল দিন।
  2. বাটনটি এমনভাবে ডিজাইন করুন যাতে এটি ক্লিক করা হলে CardService.TextButton.setOnClickAction() এর মাধ্যমে নিম্নলিখিত submitForm অ্যাকশনটি কল হয়:
/**
 * 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 হেল্পার ফাংশনটি ফর্মের প্রতিক্রিয়াগুলোকে একটি অ্যারেতে রূপান্তর করা সহজ করে তোলে, যা পরে স্প্রেডশীটে যুক্ত করা যায়।

সবশেষে, appsscript.json এর oauthScopes সেকশনটি আবার আপডেট করে https://www.googleapis.com/auth/spreadsheets স্কোপটির জন্য অনুরোধ করুন। অনুমোদিত হলে, এই স্কোপটি অ্যাড-অনকে একজন ব্যবহারকারীর গুগল শিটস পড়তে এবং পরিবর্তন করতে দেয়।

"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/ -এ গিয়ে একটি তৈরি করুন।

এখন অ্যাড-অনটি পুনরায় চালান এবং ফর্মটি জমা দেওয়ার চেষ্টা করুন। নিশ্চিত করুন যে আপনি স্প্রেডশিট ইউআরএল (Spreadsheet URL) ফর্ম ফিল্ডে আপনার গন্তব্য ইউআরএল-এর সম্পূর্ণ ইউআরএলটি প্রবেশ করিয়েছেন।

৬. Properties সার্ভিসের মাধ্যমে মানগুলো সংরক্ষণ করুন।

অনেক সময় ব্যবহারকারীরা একই স্প্রেডশিটে অনেকগুলো খরচ নথিভুক্ত করেন, তাই কার্ডটিতে ডিফল্ট মান হিসেবে সবচেয়ে সাম্প্রতিক স্প্রেডশিটের ইউআরএলটি দেওয়া সুবিধাজনক হবে। সবচেয়ে সাম্প্রতিক স্প্রেডশিটের ইউআরএলটি জানার জন্য, প্রতিবার অ্যাড-অনটি ব্যবহার করার সময় আমাদের সেই তথ্যটি সংরক্ষণ করতে হবে।

Properties সার্ভিসটি আমাদেরকে কী-ভ্যালু পেয়ার সংরক্ষণ করতে দেয়। আমাদের ক্ষেত্রে, একটি উপযুক্ত কী হতে পারে "SPREADSHEET_URL" এবং ভ্যালু হবে ইউআরএলটি নিজেই। এই ধরনের ভ্যালু সংরক্ষণ করার জন্য, আপনাকে Cards.gs এর submitForm এমনভাবে পরিবর্তন করতে হবে, যাতে শীটে একটি নতুন সারি যুক্ত করার সাথে সাথে স্প্রেডশীটের ইউআরএলটি একটি প্রপার্টি হিসেবে সংরক্ষিত হয়।

উল্লেখ্য যে, প্রপার্টির তিনটি স্কোপের মধ্যে যেকোনো একটি থাকতে পারে: স্ক্রিপ্ট, ইউজার, বা ডকুমেন্টডকুমেন্ট স্কোপটি জিমেইল অ্যাড-অনের ক্ষেত্রে প্রযোজ্য নয়, যদিও কোনো নির্দিষ্ট গুগল ডক বা শিটের তথ্য সংরক্ষণের জন্য এটি একটি ভিন্ন ধরনের অ্যাড-অনের ক্ষেত্রে প্রাসঙ্গিক। আমাদের অ্যাড-অনের জন্য কাঙ্ক্ষিত আচরণটি হলো, একজন ব্যক্তি যেন ফর্মে ডিফল্ট অপশন হিসেবে তার নিজের (অন্য কারো নয়) সবচেয়ে সাম্প্রতিক স্প্রেডশিটটি দেখতে পান। ফলস্বরূপ, আমরা স্ক্রিপ্ট স্কোপের পরিবর্তে ইউজার স্কোপ নির্বাচন করি।

স্প্রেডশীটের URL সংরক্ষণ করতে PropertiesService.getUserProperties().setProperty() ব্যবহার করুন। Cards.gs এর submitForm এ নিম্নলিখিতটি যোগ করুন:

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

এরপর Helpers.gs এর getSheetUrl ফাংশনটি এমনভাবে পরিবর্তন করুন যাতে এটি স্টোরড প্রপার্টিটি রিটার্ন করে এবং ব্যবহারকারী প্রতিবার অ্যাড-অনটি ব্যবহার করার সময় সবচেয়ে সাম্প্রতিক 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');
}

অবশেষে, প্রপার্টি সার্ভিস অ্যাক্সেস করার জন্য স্ক্রিপ্টটিকেও অনুমোদিত করতে হবে। আপনার অ্যাড-অনকে প্রপার্টি তথ্য পড়া ও লেখার অনুমতি দিতে, আগের মতোই ম্যানিফেস্টে https://www.googleapis.com/auth/script.storage স্কোপটি যোগ করুন।

৭. জিমেইল বার্তাটি বিশ্লেষণ করুন

ব্যবহারকারীদের সময় সত্যিই বাঁচাতে, চলুন ইমেল থেকে খরচ সংক্রান্ত প্রাসঙ্গিক তথ্য দিয়ে ফর্মটি আগে থেকেই পূরণ করে দিই। আমরা 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 এর সমস্ত ফাংশনের জন্য আপনার নিজস্ব ইমপ্লিমেন্টেশন তৈরি করার পরে, আপনার অ্যাড-অনটি ব্যবহার করে দেখুন! রসিদগুলো খুলুন এবং একটি স্প্রেডশিটে সেগুলো লগ করা শুরু করুন!

৮. কার্ডের মাধ্যমে ফর্মটি পরিষ্কার করুন।

যদি Expense It! একটি খোলা ইমেইলে কোনো খরচ ভুলভাবে শনাক্ত করে এবং ভুল তথ্য দিয়ে ফর্মটি পূরণ করে ফেলে, তাহলে কী হবে? ব্যবহারকারী ফর্মটি খালি করে দেবেন। CardAction ক্লাসটি আমাদের এমন একটি ফাংশন নির্দিষ্ট করার সুযোগ দেয়, যা অ্যাকশনটিতে ক্লিক করা হলে কল করা হয়। চলুন, ব্যবহারকারীকে দ্রুত ফর্মটি খালি করার একটি উপায় দিতে এটি ব্যবহার করি।

createExpensesCard এমনভাবে পরিবর্তন করুন যাতে এটি যে কার্ডটি রিটার্ন করে, সেটির একটি কার্ড অ্যাকশন থাকে যার লেবেল "Clear form" এবং ক্লিক করা হলে নিম্নলিখিত clearForm ফাংশনটি কল হয়, যা আপনি Cards.gs ফাইলে পেস্ট করতে পারেন। ফর্মটি ক্লিয়ার করার পরেও যেন স্ট্যাটাস মেসেজটি থেকে যায়, তা নিশ্চিত করার জন্য আপনাকে অ্যাকশনটিতে `status` নামের একটি প্যারামিটার হিসেবে opt_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();
}

৯. একটি স্প্রেডশীট তৈরি করুন

বিদ্যমান স্প্রেডশীট সম্পাদনা করার জন্য গুগল অ্যাপস স্ক্রিপ্ট ব্যবহার করা ছাড়াও, আপনি প্রোগ্রাম্যাটিকভাবে একটি সম্পূর্ণ নতুন স্প্রেডশীট তৈরি করতে পারেন। আমাদের অ্যাড-অনের জন্য, চলুন ব্যবহারকারীকে খরচের জন্য একটি স্প্রেডশীট তৈরি করার সুযোগ দিই। শুরু করার জন্য, 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);

এখন, যখন ব্যবহারকারী "New Sheet" বোতামে ক্লিক করেন, তখন অ্যাড-অনটি একটি নতুন স্প্রেডশীট তৈরি করে, যা একটি হেডার সারি দিয়ে ফরম্যাট করা থাকে এবং এই সারিটি এমনভাবে স্থির করা থাকে যে তা সর্বদা দৃশ্যমান থাকে। ব্যবহারকারী ফর্মে নতুন স্প্রেডশীটটির জন্য একটি শিরোনাম নির্দিষ্ট করেন, যদিও ফর্মটি খালি থাকলে ব্যবহারের জন্য একটি ডিফল্ট মান অন্তর্ভুক্ত করা একটি ভালো বিকল্প হতে পারে। আপনার createExpensesSheet ফাংশনটির বাস্তবায়নে, বিদ্যমান কার্ডটির প্রায় অনুরূপ একটি কার্ড ফেরত দিন, সাথে একটি উপযুক্ত স্ট্যাটাস বার্তা যোগ করুন এবং URL ফিল্ডটি নতুন স্প্রেডশীটটির URL দিয়ে আগে থেকেই পূরণ করে দিন।

১০. অভিনন্দন!

আপনি সফলভাবে একটি জিমেইল অ্যাড-অন ডিজাইন ও বাস্তবায়ন করেছেন, যা ইমেইল থেকে কোনো খরচ খুঁজে বের করে এবং ব্যবহারকারীদের মাত্র কয়েক সেকেন্ডের মধ্যে সেই খরচটি একটি স্প্রেডশিটে লিপিবদ্ধ করতে সাহায্য করে। আপনি একাধিক গুগল এপিআই-এর সাথে ইন্টারফেস করার জন্য গুগল অ্যাপস স্ক্রিপ্ট ব্যবহার করেছেন এবং অ্যাড-অনটির একাধিকবার ব্যবহারের মধ্যে ডেটা সংরক্ষণ করেছেন।

সম্ভাব্য উন্নতি

Expense It!-কে আরও উন্নত করার সময় আপনার কল্পনাকে পথ দেখাতে দিন, তবে এটিকে আরও বেশি কার্যকরী একটি পণ্য বানানোর জন্য এখানে কিছু ধারণা দেওয়া হলো:

  • ব্যবহারকারী খরচ নথিভুক্ত করার পর স্প্রেডশিটের লিঙ্ক।
  • খরচের লগিং সম্পাদনা বা বাতিল করার সুবিধা যোগ করুন।
  • ব্যবহারকারীদের অর্থপ্রদান ও অর্থ অনুরোধ করার সুযোগ দিতে বাহ্যিক এপিআই সংযুক্ত করুন।

আরও জানুন