Send-to-kindleを使ってたくさんの人へ書籍データを送りたいので、GoogleDrive + Spreadsheet + GoogleAppsScript で実現する

## やりたいこと

KindleへEmail経由で書籍データを送ると、すぐに読めるようになるSend-to-Kindle。
とても便利だけど、書籍データをたくさんの人にメーラーで手動送信するとなると手間がかかりすぎる。
リストを作って一気に送りたいよね。

## アーキテクチャ

現場の非エンジニアでも扱えるように、GSuiteの範囲内で全て用意する。

- Google Spreadsheet
- Google Apps Script (GAS) 
- Google Drive

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649785/88f3d6a2-d661-0914-8fe7-7bfaae72df0f.png)


## 手順

1. Spreadsheetを用意する
2. Google Driveの特定の場所に書籍データを格納する
3. Spreadsheetからスクリプトを作成し、Send-to-kindleを使って書籍データを送る

### 1. Spreadsheetを用意する

実行のためのボタンを置いておくシートと、送信先アドレスや書籍データを格納するリスト用のシートを作る。
ここでは、リスト用シート名を"list"としている。（後で使う）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649785/bdac2b7b-0c89-f00f-0ccd-59abb50c8d4c.png)

挿入→図形描画、でボタンを作り、画面に貼り付けた後、右クリック→スクリプトを割り当てで、呼び出す関数名を記入する。
ここでは、"sendBook"としておく。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649785/5d275a47-5496-4c86-3a58-62ca897a1a58.png)

### 2. Google Driveの特定の場所に書籍データを格納する

任意の場所に書籍データ格納用フォルダを作成する。
URLにあるフォルダIDは、後で使うのでメモしておく。

https://drive.google.com/drive/folders/[フォルダID]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649785/63857cee-b4a2-4fab-4bbc-ac1d2e3876dc.png)

### 3. Spreadsheetからスクリプトを作成し、Send-to-kindleを使って書籍データを送る

最終的にはこんなコード。ポイントとなる関数は後述する。

```js:コード.gs
function sendBook() {
  // 実行確認
  if(Browser.msgBox("確認", "ファイルを送りますか？", Browser.Buttons.OK_CANCEL) == "cancel") {
    return;
  }

  // 電子書籍データが格納されているフォルダ
  var folder = DriveApp.getFolderById('XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX');
  
  // アドレス、ファイルリスト取得
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('list');
  const sheetData = sheet.getDataRange().getValues();
  
  // 行ごとに処理
  for (var i = 1; i < sheetData.length; i++) {
    var address = sheetData[i][0];
    var filename = sheetData[i][1];
    var mobi = folder.getFilesByName(filename).next();

    // メールを送信
    GmailApp.sendEmail(address, '', ' ', {attachments: [mobi]}); 
  }

  Browser.msgBox("完了しました");
}
```

#### Browser.msgBox()
画面にダイアログを出す関数。ボタンを押すたびにファイルを送ると大変なので、確認したのち実施するようにしておく。

#### DriveaApp.getFolderById()
Google Driveの書籍データ格納フォルダを指定する。

#### SpreadsheetApp.getActiveSpreadsheet().getSheetByName()
Spreadsheetの、指定のシート情報を取得する。

#### sheet.getDataRange().getValues();
行データを配列で取得する。あとでfor文などを使い、1行づつ読み込んで使う。

#### folder.getFilesByName(filename).next()
先ほどのDriveフォルダから、名前の一致するファイルを取得する。リストで取ってくるので、1件欲しい場合はnext()で絞る。

#### GmailApp.sendEmail()
今回の主役。
これを呼ぶだけで添付メールを送ることが出来る。

Send-to-kindleを使うときに注意するポイントがある。
本文が空だと「ファイル添付されてない」ってKindleから怒られてしまう。

なので、

``` GmailApp.sendEmail(address, '', ' ', {attachments: [mobi]}); ```
と、本文にスペース１つでいいので、空にしないでおこう。

## 実行結果

Kindleのパーソナル・ドキュメントに届いていることを確認する。（数分かかる）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/649785/faa360ed-5d52-26f3-420e-ac4539e5aa13.png)


## 注意点
このスクリプトから送ると、メール送信者は実行者のアドレスになる。
あらかじめKindleの設定に、実行者のアドレスを登録して許可しておく必要がある。

別のアドレスを設定したい場合、
GmailApp.sendEmail関数でFromアドレスを指定することができるが、自由に設定できるわけではなく、
このマクロ実行者のエイリアスの中からしか選べない。

参考：
[sendEmail(recipient, subject, body, options)](https://developers.google.com/apps-script/reference/gmail/gmail-app#sendemailrecipient,-subject,-body)

>the address that the email should be sent from, which must be one of the values returned by getAliases()
> (fromに設定するEmailアドレスはgetAliases()が返すもののいずれかでなければならない)

エイリアスに自分のアドレス以外を登録して送りたい場合は、以下記事を参考に。

[[Google Apps Script]別のアドレスからメールを送信する。](https://www.ka-net.org/blog/?p=4441#comment-10343)