Google Apps Script

Google Apps Script プログラミング (5) SendGrid (Web API v3)を使ってメールを送る

※この記事は、2023/01/10 に更新しました。

※この記事は、以下の記事と関連があります

上記の記事では、Gmail アカウントを使って一人または複数の人にメールを送りました。Google Apps Script の GmailApp クラスを使うと、簡単にメールが送れることを説明しました。

メール送信での課題

上記記事のスクリプトの場合、課題となるのは、「個人の Gmail アカウントでスクリプトを実行すると、作成した人のメールアドレスがそのまま From (送信元)に書かれるため、個人アドレスが開示されてしまう」という点でした。

メールを送信したいけれど、個人のメールアドレスを開示はしたくない。こういう時に、メール配信サービス「SendGrid」を使うと、個人の Gmail メールアドレスを開示することなくメールを送信できます。

今回のゴール

  • メール送信元は、no-reply@ako.com という架空のアドレスを差出人に設定する
    → From (送信元・差出人)の個人アドレスが、外部に公開される状態を避けられる
  • To(受取人)には、存在するアドレス(例えば代表窓口となるメールアドレス)を設定する
    → メールである以上、To は必須入力項目なので、空欄にはしない
  • Bcc には、メールを受け取る対象者全員のメールアドレスを設定する
    → 受取人以外の送信先メールアドレスを伏せて送信できる

SendGrid とは

SendGrid

全世界で利用されているメール配信サービス(クラウドサービス)で、アカウントを作成するだけで即日メールを送信できます。メールサーバを構築する必要がありません。詳しいことは、日本の正規代理店・構造計画研究所にて、日本語で紹介されている公式説明をご覧ください。

今回は、Freeプラン(0円/月、通数上限 12,000通/月)を利用します。

今回の例で申し上げますと、これまで書いてきたスクリプトを活かしつつ、メール送信に関わるところを SendGrid に任せたい、といった流れです。

本投稿の参考記事

以下の記事を参考にしています。先に、こちらをさらっと見ておいていただくとよいと思います。

それでは、以下より始めていきましょう。

手順

SendGrid でアカウントを取得する

まずは、こちらから新規会員登録(アカウントを取得)しましょう。

登録ステップは、以下の通りです。

  1. メールアドレスの入力
    新規会員登録の最初のページです。メールアドレスを入力、利用規約・プライバシーポリシーに同意し、「確認メールを送付する」をクリックしてください

  2. 確認メールの送付
    確認メールには「ユーザ情報を登録」というボタンが表示されます。ボタンをクリックして、本登録をしてください

  3. 個人情報登録
    本登録では、「個人情報登録」と「ご利用目的」を細かく入力する欄があります

  4. 登録完了
    登録内容に基づいて審査が行われます。審査が完了するまで、暫くお待ちください。
    審査に通過すると「SendGrid にようこそ!」といった件名のメールが届きます

SendGrid APIキーの生成

アカウントを作成したら、API Key を生成しましょう。

API (Application Programming Interface) とは、アプリケーションの一部を外部に向けて公開し、他のアプリケーションと機能を共有・連携して使用できるようにしてくれるものです

API の実行時には、「外部との機能の共有・連携」をやり取りするため、予め「適正な利用ができる相手なのか、認証を受ける」必要があります。この時に必要となるのが、API Key です。

今回の例では、Google Apps Script を使って、SendGrid というサービスを利用します。そのため、SendGrid が外部に設けている窓口に対して、Google Apps Script は、適切に接続・認証を受けるための SendGrid API Key を持っていることが重要です。

(1) ログインをします

(2) ログイン後のマイページで、「SendGrid ダッシュボード」ボタンをクリックします

(3) SendGrid ダッシュボードの左側 [ Settings ] → [ API Keys ] をクリックします

SendGrid ダッシュボードから操作します

(4) [ Create API Key ] を押します

(5) Create API Key の入力項目に、必要なことを書きましょう。

  • API Key Name は、適宜名前を付けます
  • API Key Permissions は、その API Key で実行できる内容を指定します
    本投稿はテストなので、Full Access を選びます。実運用の際には、Restricted Access を選択し、APIキーの権限を細かく設定・制限してください。
  • 設定を終えたら、[ Create & View ] をクリックします

(6) API Key が表示されます
 この API Key は二度と表示されません(後から ダッシュボードで探しても見つかりません)ので、ウィンドウを閉じる前に必ず、「メモ帳」などを使って確実に保存してください。後ほど使います。

ここで表示される API Key は、二度と表示されません

※ この後で表示される API Keys ウィンドウで表示されている「API Key ID」から始まる文字列は、API Key そのものではありませんので、くれぐれもご注意下さい。

API KEY はマスキングされていて見えません

Google スプレッドシート の用意

前回と同じ状況を使います。CSVファイルの読み込みなど、必要な設定は Google Apps Script プログラミング (4) シートの情報を使ってメールを送る をご覧下さい。

見た目は 記事(4) と一緒です

Google Apps Script の用意

(1) コード.gs の変更

 前回書いていただいたスクリプトをもとに、以下の通り書きます。

 コード.gs には、こちらのコードを貼り付けてください。

const myFunction = () => {

  // データを取得する対象となる Sheet の選択
  const sheet = SpreadsheetApp.getActiveSheet();
  // データの件数(行数。見出しを含めない)
  const sheetDataLastRow  = sheet.getLastRow() - 1;
  // スプレッドシートのデータ(見出しを含めない)をまとめて取得する
  const sheetData = sheet.getRange(2,1,sheetDataLastRow,3).getValues(); 
  
  // 名前 列のデータを配列として抽出
  const akoName = sheetData.map(item => item[0]);
  // メールアドレス 列のデータを配列として抽出
  const akoEmail = sheetData.map(item => item[1]);
  // 送信対象 列のデータを配列として抽出
  const flags = sheetData.map(item => item[2]);

  let addressList = [];
  let nameList = "";

  // 送信該当者のメールアドレスだけを、addressList に入れる
  // 表門担当者を、横書きリストにする
  for(let num = 0; num <= sheetDataLastRow; num++) {
    if(flags[num]) {
      addressList.push(akoEmail[num]);
      nameList = nameList + akoName[num] + "\n";
    }
  }

  readyToSendEmail(addressList, nameList);
}

// メール送信準備を行う
const readyToSendEmail = (okurisakiAddress, member) => {

  const honbun = "12月14日は、吉良邸への討ち入りです。\n\n" + "■表門担当者\n" + member;
  const kenmei = "連絡:討ち入り日程について";
  const emailFrom = "no-reply@ako.com";
  const nameFrom = "名無しの権兵衛"

  // SendGrid Web API v3 を使う
  // daihyou@emailaddress.com のところには、代表窓口メールアドレスを入れる
  sendEmailBySendGrid("daihyou@emailadress.com",okurisakiAddress,kenmei,emailFrom,nameFrom,honbun);

  return 0;
}

(2) sendgrid.gs の作成と入力

 今回は、同じプロジェクトの中に、新しいスクリプト sendgrid.gs を作成します。

1) プロジェクトのウィンドウから、左上にある「ファイル」の を押して、スクリプトを選びます

スクリプトを選択します

2) 入力枠に、スクリプト名 sendgrid と入力してエンターキーを押して下さい。自動的に、sendgrid.gs となります

sendgrid と名前を付けてエンターキーを押します

3) 新しいスクリプト sendgrid.gs の枠が出来ました

4) 以下のスクリプトを、入力するか、コピーして貼り付けてください

// SendGrid V3 Mail Send API を使って、メールを送信する ---
// スクリプトプロパティは、「プロジェクトの設定」->「スクリプトプロパティの追加」を行なう
const scriptProperties = PropertiesService.getScriptProperties();
const SEND_GRID_ENDPOINT = scriptProperties.getProperty('SEND_GRID_ENDPOINT');
const SEND_GRID_API_KEY = scriptProperties.getProperty('SEND_GRID_API_KEY');


// メール送信用スクリプト ---------------------------------
const sendEmailBySendGrid = (toAddress, bccAddresses, subject, from, from_name, body_text) => {
  // 送信先メールアドレスの配列の長さから、後に push() する数を定める
  // bccAddresses[0]は、最低必要な一件なのでオブジェクト宣言時に記述が必要
  const count = bccAddresses.length;

  let body = {
    personalizations: [
      {
        to: [
          {
            email: toAddress,
          },
        ],
        bcc: [
          {
            email: bccAddresses[0],
          },
        ],
        subject: subject,
      },
    ],
    from: {
      email: from,
      name: from_name,
    },
    content: [
      {
        // text/plain で指定しないと \n で改行されない
        type: "text/plain",
        value: body_text,
      },
    ],
  };

  // 複数宛先へのメール送信に合わせ、bcc オブジェクトに push() する
  for (let i = 1; i < count; i++) {
    body.personalizations[0].bcc.push({ email: bccAddresses[i] });
  }

  // メール送信に必要な記述
  const payload = JSON.stringify(body);
  UrlFetchApp.fetch(SEND_GRID_ENDPOINT, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Authorization: "Bearer " + SEND_GRID_API_KEY,
    },
    payload: payload,
  });
}

(3) スクリプト プロパティの設定(※2023/01/10 追記)

 先程取得した SendGrid の API Key を、「スクリプト プロパティ」として設定します。スクリプト内で使うプロパティをプロジェクトの設定として決めておくことで、スクリプト内に直接 API Key を書くことを避けています。

 これは、スクリプト内に直接、SendGrid API Key を記載したままにすると、エディタを見れば簡単に他人が API Key を知ることになり、好ましい状態ではないからです。また、Google Apps Script で書いたスクリプトを GitHub 上に公開した場合、API Key が公開されてします。

 前回までの記事では、分かりやすくする目的で API Key を直接書いて挿入していた(ハードコーディング)のですが、良くないと反省しまして「スクリプト プロパティ」を使う形に変更しています。

1) 「プロジェクトの設定」を開く

 左側のメニューを使って、いま作業をしている「エディタ」から、「プロジェクトの設定」へ移動します。

プロジェクトの設定へ移動

2) スクリプト プロパティを追加します

 画面下へ移動すると「スクリプト プロパティ」の表示があります。ここにある「スクリプト プロパティを追加」をクリックします。

「スクリプト プロパティを追加」を押す

 「スクリプト プロパティを追加」を押すと、プロパティと値を入力する枠が表示されます。ここに、今回は、SEND_GRID_ENDPOINT と SEND_GRID_API_KEY をそれぞれ入力します。追加するのは、2つのプロパティなので、2回押すと枠が 2つできます。

 追加する値は、以下の通りです。

プロパティ備考
SEND_GRID_ENDPOINThttps://api.sendgrid.com/v3/mail/send皆さん共通です
SEND_GRID_API_KEY先程控えたSendGrid APIキーを入力皆さん違います

画面で見ると、このような形になります。

 入力を終えたら、「スクリプト プロパティを保存」を押してください。

 一度保存すると、プロパティと値が灰色に表示されるため、容易に編集できなくなります。編集する場合や、更に追加してプロパティを設定する場合は、「スクリプト プロパティを編集」をクリックしてください。

3) エディタに戻り、myFunction を実行する

 左側のメニューを使って、いま作業をしている「プロジェクトの設定」から、「エディタ」へ移動します。更に、コード.gs に戻って、myFunction を実行してみてください。

 今回の赤穂浪士たちのメールアドレスは、全ていい加減なので送っても到達しません。正規のアドレスを使ってテストして下さい。

sendgrid.gs の詳しい説明

公式ドキュメント v3 Mail Send API 概要 – ドキュメント | SendGrid の記述に合わせて、記述しています。

  • personalizations の JSON パラメータ to必須 Yes とあり、制限に「最低1」と書かれています
    → Bcc でメールを送りたいからといって、to を無視はできません
    → 会社代表のメールアドレスあたりを使うのが適切です(送信できたかの確認にもなる)

  • personalizations の JSON パラメータには bcc存在しています(設定が必須ではありません)
    → 今回の場合、一回の sendEmailBySendGrid() の実行で、複数名の Bcc に名を連ねた人にメールを送りたいと考えています。
    → 最初(一人目)のメールアドレスは、 bccAddresses[0] を使って、body の宣言に合わせて入れます。それ以外の対象者は、44 ~ 46 行目の for 文を使って、bcc オブジェクトの中に、データを push して対応します。このため、12行目で 配列 bccAddress の長さを求めた変数 count を用意しています。

この personalization の設定をどう使うかは「メールをどう送りたいのか」という仕様に関わるところです。実運用をする場合、じっくりお話ししてご検討ください。


49行目から57行目の「メール送信に必要な記述」は、参考記事並びに以下の公式ドキュメントを参考にしています。

SendGrid for Developers – Getting started with the SendGrid API

SendGrid API (Web API) の使い方を説明しています

ここでは、Google Apps Script ではなく、curl コマンドを使った例で使い方が説明されています(curl については、ここでは説明しません)。

POST リクエストを使うこと、送信先のURLを記述すること、header 情報の Content-Type・Authorization を記述すること、メールに関するdata(通信をする際のデータ本体・ペイロード)を記述することは、共通しているのが何となく伝わると嬉しいです。

Google Apps Script でこれらを実行するために、以下のような手順を踏んでいました。

  • 49行目では、送信するデータ本体を、JSON(JavaScript Object Notation) というフォーマットに変換しています。
    • 変換対象となるデータ本体は、14行目から46行目までで準備した、body というオブジェクトです
    • JSON.stringify() メソッドを使うことで、body オブジェクトをJSON 文字列に変換しています。SendGrid のほうで、このデータは、JSON にしてほしいと指定がされているために、変換していたのです。
      JSON.stringify() – JavaScript | MDN
POSTリクエストをする際、payload は JSON で送信しなければなりません
  • 50行目から57行目では、Google Apps Script で Web API を使う(HTTPリクエストをする)記述をしています。UrlFetchApp.fetch() メソッドを使うと、HTTPリクエストを実行できます。
UrlFetchApp.fetch() のパラメータ説明

実行上の注意点

繰り返しになり恐縮ですが、今回の赤穂浪士たちのメールアドレスは、全ていい加減なので送っても到達しません。正規のアドレスを使ってテストして下さい。

ただし、テストの目的で、スプレッドシート上に同一メールアドレスを複数個書かないようにしてください(警告がでます)

この警告については、公式ドキュメントに「同じメールが一人の受信者に複数回配信されるのを防ぐために、SendGridはリクエストでメールアドレスが重複していないことを確認している。そのため、同一の Personalization の中で、重複するメールアドレスの利用を許可していない。」と書かれています。

いきなり難しくなってしまいました

本投稿は、自分自身の備忘録を兼ねているような記事でした。皆さんもお手元で試していただき、ご自身にとって楽しいプログラミングライフにつないでいただけたらなと、考えております。