GASでGmailのテンプレAddonツールを作る

GAS

どうやらGASにはまだまだ知らない機能があったようで・・・

日本語では最近の記事がヒットしないのですが、CardServiceというメソッドがあります。
これをうまく使うとGmailに宛先、CC、BCC、件名、本文などなどをテンプレとして登録し、一発で呼び出すアドオンを実装できるみたいなので作りました。

スポンサーリンク

完成イメージ

Gmailでメールを新規作成するときに、こんな感じでテンプレを呼び出せるようにします。

定型的なメールをよく使う人には意外と便利そうじゃないでしょうか?

では、具体的なコードを載せていきます。

コード書く前の準備

いつも通り、スプレッドシートを公開しておきます。

Gmailテンプレ
テンプレ 表示名1,表示名2,To,CC,BCC,件名(必須),本文(必須),管理メモ 【社内向け】,チーム内広報,dummy1@aaa.bbb,dummy2@aaa.bbb,dummy3@aaa.bbb,【チーム内広報】お知らせ,各位 お...

各自でマイドライブにコピーして使ってください。
(たまに編集権限をリクエストされる方がいますが、コピーして使ってくださいね!)

コピーしたらスプレッドシートの拡張機能→AppsScriptを開いて
GASのマニフェストファイルというのを編集できるようにしておきましょう。

コード

まずはコード.gsです。コピペでOKです。

function createTemplete() {
  //テンプレシート
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const ss_url = ss.getUrl();
  const sheet = ss.getActiveSheet();
  const sheet_id = sheet.getSheetId();
  const sheet_url = ss_url + '#gid=' + sheet_id;
  //アドオンのボタン設定
  const edit_button = CardService.newTextButton()
    .setText('編集')
    .setTextButtonStyle(CardService.TextButtonStyle.FILLED)
    .setBackgroundColor("#696969")
    .setOpenLink(CardService.newOpenLink()
      .setUrl(sheet_url)
    );
  const buttons = CardService.newCardSection();
  //テンプレシートのデータ取得
  const data = sheet.getDataRange().getValues().filter(function(x){return !(x === null || x === undefined || x === "");});
  const display_name1_idx = 0;
  const display_name2_idx = 1;
  const to_idx = 2;
  const cc_idx = 3;
  const bcc_idx = 4;
  const subject_idx = 5;
  const body_idx = 6;
  //アドオンへテンプレデータを連携
  if(data.length == 1){
    buttons.addWidget('テンプレが未設定です。');
  }else{
    for(let i = 1; i < data.length; i++){
      buttons.addWidget(CardService.newTextButton()
        .setText(data[i][display_name1_idx] + data[i][display_name2_idx])
        .setOnClickAction(CardService.newAction()
          .setFunctionName('addTemplete')
          .setParameters({
            'to': data[i][to_idx],
            'cc': data[i][cc_idx],
            'bcc': data[i][bcc_idx],
            'subject': data[i][subject_idx],
            'body': data[i][body_idx]
          })
        )
      
      )
    }
  }
  const card = CardService.newCardBuilder()
    .addSection(CardService.newCardSection()
      .addWidget(edit_button)
    )
    .addSection(buttons)
    .build();
  return [card];
}

function addTemplete(e){
  //引数から各値を取得
  const to = e.parameters['to'] ? e.parameters['to'].split(',') : [];
  const cc = e.parameters['cc'] ? e.parameters['cc'].split(',') : [];
  const bcc = e.parameters['bcc'] ? e.parameters['bcc'].split(',') : [];
  const subject = e.parameters['subject'] ? e.parameters['subject'] : "";
  const body = e.parameters['body'] ? e.parameters['body'] : "";
  const sp_body = body.split(String.fromCharCode(10)).join('<br />');//HTMLフォーマット変換
  Logger.log("To: " + to + "\nCC: " + cc + "\nbcc: " + bcc + "\n件名: " + subject + "\n本文: \n" + body + "\nHTML: \n" + sp_body);
  //各値をカードサービスで扱えるように準備。to,cc,bccが空白だとエラーが出るので初期値に[{"email": ""}]を設定すること。
  let card_to = CardService.newUpdateDraftToRecipientsAction().addUpdateToRecipients([{"email": ""}]); 
  if(to.length > 0){card_to = CardService.newUpdateDraftToRecipientsAction().addUpdateToRecipients([to]);}
  let card_cc = CardService.newUpdateDraftCcRecipientsAction().addUpdateCcRecipients([{"email": ""}]);
  if(cc.length > 0){card_cc = CardService.newUpdateDraftCcRecipientsAction().addUpdateCcRecipients([cc]);}
  let card_bcc = CardService.newUpdateDraftBccRecipientsAction().addUpdateBccRecipients([{"email": ""}]);
  if(bcc.length > 0){card_bcc = CardService.newUpdateDraftBccRecipientsAction().addUpdateBccRecipients([bcc]);}
  let card_subject = CardService.newUpdateDraftSubjectAction().addUpdateSubject("");
  if(subject != ""){card_subject = CardService.newUpdateDraftSubjectAction().addUpdateSubject(subject);}
  let card_body = CardService.newUpdateDraftBodyAction()
      .addUpdateContent(
        "",
        CardService.ContentType.MUTABLE_HTML
      )
      .setUpdateType(CardService.UpdateDraftBodyType.IN_PLACE_INSERT);
  if(body != ""){
    card_body = CardService.newUpdateDraftBodyAction()
      .addUpdateContent(
        sp_body,
        CardService.ContentType.MUTABLE_HTML
      )
      .setUpdateType(CardService.UpdateDraftBodyType.IN_PLACE_INSERT);
  }
  let result = CardService.newUpdateDraftActionResponseBuilder()
      .setUpdateDraftToRecipientsAction(card_to)
      .setUpdateDraftCcRecipientsAction(card_cc)
      .setUpdateDraftBccRecipientsAction(card_bcc)
      .setUpdateDraftSubjectAction(card_subject)
      .setUpdateDraftBodyAction(card_body)
      .build(); 
  return result;
}

続いて、マニフェストファイルを編集しましょう。
全体をコピペで大丈夫です。

{
  "timeZone": "Etc/GMT-9",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "gmail": {
    "name": "Gmailテンプレート",
    "logoUrl": "https://www.gstatic.com/images/icons/material/system/1x/label_googblue_24dp.png",
    "openLinkUrlPrefixes": [
      "https://mail.google.com/"
    ],
    "primaryColor": "#4285F4",
    "secondaryColor": "#0000ff",
    "composeTrigger": {
      "selectActions": [
        {
          "text": "テンプレートを作成",
          "runFunction": "createTemplete"
        }
      ]
    }
  }
}

その後、ctrl + s でプロジェクトを保存してください。

で、画面右上の「デプロイ」から「デプロイをテスト」をクリックしてください。
ポップアップしてきた画面の右下に「インストール」とあるので、インストールをクリック、
完了をクリックで準備完了です。

Gmailを開いてください。
設定を見ると「アドオン」タブに「インストール済みのデベロッパーアドオン」というのが確認できると思います。
確認できない場合はアドオンを有効化し再度インストールしてみてください。

さらに、Gmailのサイドバーに下記画像のようなアイコンが増えていると思います。

で、肝心の機能の箇所ですが、
新規メールを作成してみてください。

下記画像のように青いインデックスの画像が出てきていると思います。
クリックして「アクセスを承認」を進めてください。

そうすると「Gmailテンプレート」というのが出てくると思います。
スプレッドシートで設定したテンプレが選択できますので、表示名をクリックしてテンプレを適用してみてください。

下書きにテンプレ内容が入力されれば無事機能追加完了です。

ちなみに、件名と本文は必須にしています。
TO、CC、BCCは空白許可するコードになっていますが、他の穴あきでエラーが起きた場合はご愛嬌です。

情シスが厳しい会社だったらChrome拡張機能が使えないと思うので

自前で作った機能なのでセキュリティ等々はクリアできているはずです。
機能を実行するためにどこにもデータ送信しませんから。

Chrome拡張機能は便利なものが多いですが、他所の人が作ったものですので情シス的には信用できないのです。
特に既に審査通った拡張機能を誰かが買収したりして悪意のあるコードを埋め込んでアップデート、なんかがあるとストア審査も潜り抜けたりするらしいので。

機能としてはシンプルですが刺さる人には刺さるのではないでしょうか。

コメント

タイトルとURLをコピーしました