blastengineとkintoneを組み合わせてメールを一括送信する

kintoneは、多くの企業で使われているWebデータベースアプリケーションサービスです。テンプレートが豊富で、報告書やタスク管理、連絡網など色々と用意されています。

今回はその一つである顧客リストを使って、blastengineと組み合わせてみました。

# 機能について

- 顧客リストにあるメールアドレス宛にメールを一括送信
- エラーリストを使って次回以降送信しないようにkintoneのデータを更新

前半となるこの記事では `顧客リストにあるメールアドレス宛にメールを一括送信` について実装します。

## ユーザ登録する

blastengineにユーザ登録します。管理画面に入るためのユーザID、パスワードが手に入るので、ログインします（ユーザIDは後で使います）。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/dd84066c-7735-d55d-9e53-c782974fca71.png)


## 送信元ドメインのSPFを設定する

送信元として利用するドメイン（自分で持っているもの）の設定をします。これは任意のドメイン管理サービスで設定できますが、TXTレコードに以下のSPFを追加します。

```
txt @ v=spf1 include:spf.besender.jp ~all
```

## APIキーを取得する

ログイン後、管理画面の右上にある設定メニューに移動します。

![https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/47b2b2ac-2e41-77fe-d84f-0ae0b7541f36.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/47b2b2ac-2e41-77fe-d84f-0ae0b7541f36.jpeg)

そして設定の中で、APIキーを取得します。

![https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/2b5ca124-3020-1d39-84e4-911cd4db27e2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/2b5ca124-3020-1d39-84e4-911cd4db27e2.png)

# kintoneアプリの修正

今回は `顧客リスト`を使っていますが、そのままだと配信フラグがなかったり、フィールドの名前が日本語で使いづらかったりします。そこで以下の修正を行います。

1. フィールドの追加
2. フィールドコードの変更

## フィールドの追加

今回はメール送信というフィールドをラジオボックスで追加します。フィールドコードは `sendTarget` としています。項目は `対象` と `送信しない` としています。初期値は `対象` です。

![Untitled.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/3f40a39a-f808-ae57-7b6b-d133bf3fd307.jpeg)


## フィールドコードの変更

下記のフィールドのフィールドコードを変更しています。

| フィールド名 | フィールドコード |
| --- | --- |
| メールアドレス | email |
| 担当者名 | name |

変更したら、アプリを更新します。

# アプリを作る

今回はkintoneのJavaScript SDKを使います。これはNode.js向けに提供されています。まず適当なフォルダを作成します。

```
mkdir kintone-app
cd kintone-app
```

Node.jsプロジェクトとして初期化します。Node.jsはインストール済みであることとします。

```
npm init -y
```

## ライブラリをインストール

必要なライブラリをインストールします。

- @kintone/kintone-js-sdk
kintone SDK
- blastengine
blastengine SDK
- dotenv
環境変数の追加

```
npm i @kintone/kintone-js-sdk
npm i blastengine
npm i dotenv
```

## ファイルの作成

今回は `mail.js` というファイルを作成します。また、プロジェクト直下に `.env` ファイルを作成し、環境変数を記述します。以下は `.env` ファイルの内容です。

```
# kintoneユーザー名とパスワード
USERNAME=YOUR_USERNAME
PASSWORD=YOUR_PASSWORD
# kintoneのドメイン
DOMAIN=example.cybozu.com
# kintoneのアプリID
APPID=1
# blastengineのユーザーIDとAPIキー
BLASTENGINE_USERID=YOUR_USERID
BLASTENGINE_APIKEY=YOUR_APIKEY
# メールの送信元
FROMNAME=blastengine管理者
FROMADDRESS=info@example.jp
# メールの件名
SUBJECT=【blastengine】テストメール
```

## ライブラリ読み込み

ここからは `mail.js` への記述です。まず最初に必要なライブラリを読み込みます。

```jsx
// dotenvを読み込み、環境変数を設定する
require('dotenv').config();

// blastengine SDKとBulkを読み込む
const { BlastEngine, Bulk } = require('blastengine');

// kintone-js-sdkとfsを読み込む
const kintone = require('@kintone/kintone-js-sdk');
const fs = require('fs');
```

## kintoneへの接続情報を作成する

`.env` ファイルに定義したユーザー名とパスワードを使って、kintoneへの接続情報を作成します。

```jsx
// kintoneへの接続情報を作成する
const auth = new kintone.Auth();
const passwordAuthParam = {
		username: process.env.USERNAME,  // kintoneにログインするためのユーザー名
		password: process.env.PASSWORD   // kintoneにログインするためのパスワード
};
auth.setPasswordAuth(passwordAuthParam);
const connParam = {
	domain: process.env.DOMAIN,   // kintoneのドメイン名
	auth,
};
connection = new kintone.Connection(connParam);

// kintoneレコード操作用のオブジェクトを作成する
const kintoneRecord = new kintone.Record({ connection });
```

## blastengineの初期化

blastengine SDKを初期化します。こちらも `.env` ファイルの内容を使います。

```jsx
// blastEngineを初期化する
new BlastEngine(process.env.BLASTENGINE_USERID, process.env.BLASTENGINE_APIKEY);
```

## 無名関数の定義

ここからはネットワーク処理があるので、非同期処理用にasync/awaitを定義します。

```jsx
// メイン処理をasync関数で囲む
(async () => {
  // ここからはこの中に書いていきます
})();
```

### kintoneからレコードを取得

kintoneを検索します。クエリーとして、メールアドレスが入力されていることと、配信対象として設定されていることを定義しています。配信対象は既存データに対しては空が設定されるので、それも含まれるようにしています。

```jsx
// kintoneアプリからレコードを取得する
const params = {
	app: process.env.APPID,  // 取得するkintoneアプリのID
	query: `sendTarget in ("", "対象") and email != ""`  // レコードの検索クエリ
};
const { records } = await kintoneRecord.getRecords(params);
```

### メール本文の読み込み

メール本文は `mail.txt` の中に記述しておきます。そのファイルの内容を読み込みます。

```jsx
// テキストファイルからメール本文を読み込む
const text = fs.readFileSync('./mail.txt', 'utf-8');
```

メールの内容は以下のようにしています。 `__name__` は配信先毎に置き換えられる文字列です。

```
__name__さん、こんにちは

これはメールの本文です。
```

### バルクメールオブジェクトの作成

blastengineのバルクメールオブジェクトを作成します。これは一括配信用のオブジェクトです。

```jsx
// Bulkオブジェクトを作成する
const bulk = new Bulk();
```

作成したバルクメールオブジェクトに、件名や送信元情報などを適用します。

```jsx
// Bulkオブジェクトにメールの情報を設定する
await bulk
	.setFrom(process.env.FROMADDRESS, process.env.FROMNAME)   // 送信元のメールアドレスと名前
	.setSubject(process.env.SUBJECT)   // 件名
	.setText(text)   // 本文
	.register();   // 送信するメールの情報をblastEngineに登録する
```

### kintoneのレコード情報を配信先として設定

先ほど取得したkintoneのレコードから、メールアドレスと名前を使って配信先として登録します。1つ目の引数がメールアドレス、2つ目の引数は置き換え文字列（メール本文で指定した `__name__` と置き換えられます）になります。

```jsx
// レコードを処理し、Bulkオブジェクトに宛先を追加する
records.map(record => {
	bulk.addTo(record.email.value, {name: record.name.value});
});
```

### 宛先情報を反映

登録した宛先情報をblastengineに反映します。

```jsx
// blastEngineに登録したメールの情報を更新する
await bulk.update();
```

### 送信する

後はメールを送信するだけです。引数として、配信日時も指定できます。

```jsx
// blastEngineを使ってメールを送信する
await bulk.send();
```

配信が完了すれば、配信ID（デリバリーID）が付与されています。

```jsx
// 送信が完了したことをログに出力する
console.log(`送信しました ${bulk.delivery_id}`);
```

## スクリプトの全体像

`mail.js` の内容は以下の通りです。

```jsx
// dotenvを読み込み、環境変数を設定する
require('dotenv').config();

// blastEngine SDKとBulkを読み込む
const { BlastEngine, Bulk } = require('blastengine');

// kintone-js-sdkとfsを読み込む
const kintone = require('@kintone/kintone-js-sdk');
const fs = require('fs');

// kintoneへの接続情報を作成する
const auth = new kintone.Auth();
const passwordAuthParam = {
		username: process.env.USERNAME,  // kintoneにログインするためのユーザー名
		password: process.env.PASSWORD   // kintoneにログインするためのパスワード
};
auth.setPasswordAuth(passwordAuthParam);
const connParam = {
	domain: process.env.DOMAIN,   // kintoneのドメイン名
	auth,
};
connection = new kintone.Connection(connParam);

// kintoneレコード操作用のオブジェクトを作成する
const kintoneRecord = new kintone.Record({ connection });

// blastEngineを初期化する
new BlastEngine(process.env.BLASTENGINE_USERID, process.env.BLASTENGINE_APIKEY);

// メイン処理をasync関数で囲む
(async () => {
	// kintoneアプリからレコードを取得する
	const params = {
		app: process.env.APPID,  // 取得するkintoneアプリのID
		query: `sendTarget in ("", "対象") and email != ""`  // レコードの検索クエリ
	};
	const { records } = await kintoneRecord.getRecords(params);

	// テキストファイルからメール本文を読み込む
	const text = fs.readFileSync('./mail.txt', 'utf-8');

	// Bulkオブジェクトを作成する
	const bulk = new Bulk();

	// Bulkオブジェクトにメールの情報を設定する
	await bulk
		.setFrom(process.env.FROMADDRESS, process.env.FROMNAME)   // 送信元のメールアドレスと名前
		.setSubject(process.env.SUBJECT)   // 件名
		.setText(text)   // 本文
		.register();   // 送信するメールの情報をblastEngineに登録する

	// レコードを処理し、Bulkオブジェクトに宛先を追加する
	records.map(record => {
		bulk.addTo(record.email.value, {name: record.name.value});
	});

	// blastEngineに登録したメールの情報を更新する
	await bulk.update();

	// blastEngineを使ってメールを送信する
	await bulk.send();

	// 送信が完了したことをログに出力する
	console.log(`送信しました ${bulk.delivery_id}`);
})();
```

## 実行する

以下のようにしてコマンドプロンプトやターミナルで実行します。

```jsx
npx node mail.js
```

以下のようなメッセージが出れば配信されているはずです。

```jsx
送信しました 105
```

## まとめ

今回はkintoneからメールアドレス情報を取得して、blastengineで配信するまでの流れを紹介しました。次回は配信結果をkintoneに反映する流れを解説します。

[エンジニア向けメール配信システム「ブラストエンジン（blastengine）」](https://blastengine.jp/)