Hexabaseはエンタープライズ企業向けのBaaS(Backend as a Service)を提供しています。認証やデータストア(データベース)、ファイルストレージ、FaaS(Function as a Service)といった機能があります。
今回はそんなHexabaseとblastengineを使って、メールマガジンを作成します。
コード
コードは blastengineMania/hexabase-mailmagazine にアップしてあります。実装時の参考にしてください。
アーキテクチャ
今回のアーキテクチャは以下のようになります。Hexabaseのデータストアに送信するメールのテンプレート(件名や本文など)、メールアドレスの2つのテーブルを用意します。
メールアドレスのテーブルにあるデータを使って、メールマガジンを送信します。
blastengineの準備
ユーザ登録する
blastengineにユーザ登録します。管理画面に入るためのユーザID、パスワードが手に入るので、ログインします(ユーザIDは後で使います)。
送信元ドメインのSPFを設定する
送信元として利用するドメイン(自分で持っているもの)の設定をします。これは任意のドメイン管理サービスで設定できますが、TXTレコードに以下のSPFを追加します。
txt @ v=spf1 include:spf.besender.jp ~all
APIキーを取得する
ログイン後、管理画面の右上にある設定メニューに移動します。
そして設定の中で、APIキーを取得します。
Hexabaseの準備
まずHexabase側の準備です。以下を順番に作成します。
- ワークスペース
任意の名前でOKです。ワークスペースIDはメモしておきます。 - プロジェクト
任意の名前でOKです。プロジェクトIDはメモしておきます。 - データストア
メールテンプレートテーブル(Mail)とメールアドレステーブル(Email)を作成します。
データストアの設計
メールテンプレートテーブル(Mail)は、以下の項目を持っています。ステータスはデフォルトで「送信前」、利用した後は「送信後」に更新されます。
項目 | 型 | 英語名 & Display ID |
---|---|---|
件名 | テキスト | subject |
本文 | テキスト | body |
送信元名 | テキスト | fromName |
送信元メールアドレス | テキスト | fromEmail |
配信ID | 数値 | deliveryId |
ステータス | ステータス | Status |
メールアドレステーブル(Email)は、以下の項目を持っています。ステータスはデフォルトで「送信可」として、送信に失敗した場合には「送信不可」ステータスになります。
項目 | 型 | 英語名 & Display ID |
---|---|---|
メールアドレス | テキスト | mailaddress |
送信エラー | テキスト | sendError |
ステータス | ステータス | Status |
ステータスの作成
ステータスはサンプルで登録されているレコードを編集する中で作成・編集できます。
メールテーブルはデフォルトが送信前、もう一つが送信後になります。メールアドレステーブルはデフォルトが送信可、もう一つが送信不可になります。
パブリックトークンの準備
Hexabaseでは認証して利用するのが基本ですが、お問い合わせの場合は認証は使わないでしょう。そこで、特定のユーザー情報に紐付くパブリックトークンを生成します。なお、執筆現在ではワークスペースごとの設定が必要です(要問い合わせ)。
実装について
プロジェクトのフォルダ作成とNode.jsプロジェクトの初期化
今回は hexabase-mail
とします。以下はこのフォルダの中で処理します。
mkdir hexabase-mail
cd hexabase-mail
npm init -y
ライブラリのインストール
必要なライブラリをインストールします。
- @hexabase/hexabase-js
- blastengine
- dotenv
- ts-node
- typescript
npm i @hexabase/hexabase-js
npm i blastengine
npm i dotenv
npm i ts-node
npm i typescript
TypeScriptプロジェクトとして初期化します。
npx tsc --init
以下は index.ts での実装内容です。
環境変数の用意
.env
を作成して、環境変数を用意します。
BLASTENGINE_USER_ID=blastengineのユーザーID
BLASTENGINE_API_KEY=blastengineのAPIキー
HEXABASE_PUBLIC_TOKEN=Hexabaseのパブリックトークン
HEXABASE_WORKSPACE_ID=Hexabaseの対象ワークスペースID
HEXABASE_PROJECT_ID=Hexabaseの対象プロジェクトID
HEXABASE_DATASTORE_MAIL_ID=Hexabaseのデータストア(メールテンプレート)のID(Mailなど)
HEXABASE_DATASTORE_EMAIL_ID=Hexabaseのデータストア(メールアドレス)のID(Emailなど)
ライブラリのインポート
必要なライブラリ(blastengine、HexabaseのSDK)、dotenvを読み込みます。
import { BlastEngine, Mail } from 'blastengine';
import { HexabaseClient } from '@hexabase/hexabase-js';
import 'dotenv/config';
blastengine、Hexabase SDKの初期化
blastengine、Hexabase SDKを初期化します。
new BlastEngine(process.env.BLASTENGINE_USER_ID!, process.env.BLASTENGINE_API_KEY!);
const client = new HexabaseClient();
メインコード
非同期処理が多いので、処理全体をasync/awaitで処理します。
(async () => {
// 以下はこの中に書きます
})();
メールのテンプレートを取得する
引数で指定されたメールのIDを使って、Hexabaseからテンプレートを取得します。
await client.setToken(process.env.HEXABASE_PUBLIC_TOKEN!);
const mailId = process.argv[2];
if (!mailId) throw new Error('メールIDが指定されていません');
await client.setWorkspace(process.env.HEXABASE_WORKSPACE_ID!);
const query = client.query(process.env.HEXABASE_PROJECT_ID!);
// メールの本文と件名
const res = await query
.from(process.env.HEXABASE_DATASTORE_MAIL_ID!)
.where([
query.condition.equalTo('i_id', mailId),
query.condition.equalTo('Status', 'before')
])
.limit(1)
.select('*');
const template = res[0];
if (!template) throw new Error(`${mailId}は存在しません`);
メールアドレスをセットする
Hexabaseにあるメールアドレス一覧を取得し、blastengineのメールオブジェクトにセットします。ステータスはメール送信が有効になっているものだけに指定します。
const emails = await query
.from(process.env.HEXABASE_DATASTORE_EMAIL_ID!)
.where(
query.condition.equalTo('Status', 'enable')
)
.limit(0)
.select('mailaddress');
const mail = new Mail;
for (const email of emails) {
mail.addTo(email.get<string>('mailaddress')!);
}
テンプレートの内容をセットする
メールオブジェクトに送信元、件名、本文をセットします。
mail
.setFrom(template.get<string>('fromEmail')!, template.get<string>('fromName')!)
.setText(template.get<string>('body')!)
.setSubject(template.get<string>('subject')!)
メールを送信する
メールを送信し、結果として得られる配信ID(デリバリーID)をHexabaseに反映します。保存した後、ステータスを送信完了 Sent
に更新します。
await mail.send();
await template
.set('deliveryId', mail.deliveryId)
.save();
await template.execute('Sent');
まとめ
今回はHexabaseと組み合わせて、メールマガジンを送信するコードを紹介しました。Hexabaseのデータストアにメールアドレスを保存しておくことで、メールマガジンの送信が簡単になります。
次回はメール送信の結果を受けて、エラーになったメールアドレスを更新するコードを紹介します。