【Google Apps Script】既存のメールを新規メールとして複製するGmailのアドオンを作る

# はじめに
送信済みのGmailを、中身はほぼ同じで、しかし宛先や本文の一部を編集してから送信したい...
本文をいちいちコピペしたり、添付ファイルをいちいちD＆Dしたりするのも面倒くさい...
ボタン一つで既存のメールを複製する、そんなアドオンを作成した。
（既存の拡張機能やアドオンには、複製できるもののリプライになってしまうものしか見つけられなかった...）

# マニフェストを作る
GASのチュートリアルに書いていることをほぼパクればOK。
今回は、メールを複製するので、アドオン名はそのまま「Mail Duplicate」とした。

```json
{
  "timeZone": "Asia/Tokyo",
  "dependencies": {
  },
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/gmail.addons.current.action.compose",
    "https://www.googleapis.com/auth/gmail.addons.current.message.readonly",
    "https://www.googleapis.com/auth/gmail.addons.execute",
    "https://www.googleapis.com/auth/spreadsheets",
    "https://www.googleapis.com/auth/spreadsheets.currentonly",
    "https://www.googleapis.com/auth/script.locale"
  ],
  "gmail": {
    "name": "Gmail Duplicate",
    "logoUrl": "{アドオンのアイコンのURL}",
    "contextualTriggers": [
      {
        "unconditional": {},
        "onTriggerFunction": "最初に起動するFunction"
      }
    ],
    "primaryColor": "#4285F4",
    "secondaryColor": "#4285F4",
    "version": "TRUSTED_TESTER_V1"
  }
}
```

# UIを作る
まずはガワから。
（JavaScriptと同じ感じで書ける）
また、このfunction名をマニフェストに「"onTriggerFunction": "buildAddOn"」としておく。

```js
/**
 * マニフェスト 'onTriggerFunction' フィールドで指定されたアドオン起動トリガー
 * 
 * @param {Object} イベントオブジェクト
 * @return {Card} カードオブジェクト
 */
function buildAddOn(e) {
  var accessToken = e.messageMetadata.accessToken;
  GmailApp.setCurrentMessageAccessToken(accessToken);

  var messageId = e.messageMetadata.messageId;
  var message = GmailApp.getMessageById(messageId);

  var subject = message.getSubject();         // 件名
  var from = message.getFrom();               // 送信元
  var to = message.getTo();                   // 送信先
  var toCc = message.getCc();                 // 送信先CC
  var toBcc = message.getBcc();               // 送信先BCC
  var mail_message = message.getBody();       // 本文
  var attachments = message.getAttachments(); // 添付ファイル

  // UI
  var buttonSet = CardService.newButtonSet();
  var duplicateButton = CardService.newTextButton()
    .setText('Mail Duplicate')
    .setOnClickAction(CardService.newAction()
      .setFunctionName('mailDuplicate')
      .setParameters({'messageId': messageId}));
  
  var card = CardService.newCardBuilder()
    .setHeader(CardService.newCardHeader()
      .setTitle(subject))
    .addSection(CardService.newCardSection()
      .addWidget(CardService.newKeyValue()
        .setTopLabel('送信元')
        .setContent(from))
      .addWidget(CardService.newKeyValue()
        .setTopLabel('送信先')
        .setContent(to))
      .addWidget(CardService.newKeyValue()
        .setTopLabel('CC')
        .setContent(toCc))
      .addWidget(CardService.newKeyValue()
        .setTopLabel('BCC')
        .setContent(toBcc))
      .addWidget(CardService.newKeyValue()
        .setTopLabel('本文')
        .setContent(mail_message))
      .addWidget(CardService.newKeyValue()
        .setTopLabel('添付ファイル')
        .setContent(attachments.length + ' 個'))
      .addWidget(duplicateButton))
    .build();
  
  return card;
}
```

「Mail Duplicate」というボタンを押せば、開いているメールが新規メールとして複製される...という想定。

# メールを複製する
メールを複製し、既存の「作成」ボタンを押した時に出てくる入力フォームに全てを当てはめたい。
今回は、一旦下書きとして複製して、それを表示するようにした。
```js
/**
 * 指定されたメールを新しいメール作成フォームに複製する
 */
function mailDuplicate(e) {
  var accessToken = e.messageMetadata.accessToken;
  GmailApp.setCurrentMessageAccessToken(accessToken);
  var messageId = e.messageMetadata.messageId;
  var message = GmailApp.getMessageById(messageId);

  var subject = message.getSubject();         // 件名
  var from = message.getFrom();               // 送信元
  var to = message.getTo();                   // 送信先
  var toCc = message.getCc();                 // 送信先CC
  var toBcc = message.getBcc();               // 送信先BCC
  var body = message.getPlainBody();          // 本文
  var attachments = message.getAttachments(); // 添付ファイル

  // メールの下書きを作成する
  var options = {attachments:attachments, bcc:toBcc, cc:toCc};
  var draft = GmailApp.createDraft(to, subject, body, options);

  return CardService.newComposeActionResponseBuilder().setGmailDraft(draft).build();
}
```

これで、複製したいメールを開き「Mail Duplicate」ボタンを押せば、下書きに複製されたものが表示される。