Notionからblastengine経由で送信したメールのエラーステータスを更新する
Notionは最近注目度の高い情報共有サービスです。Wikiのように自由テキストを保存したり、データベースのように構造化されたデータを保存もできます。
今回はそんなNotion内にあるメールアドレスを使って、blastengineと組み合わせてみました。前回はNotionデータベース上のメールアドレスを使ってメール送信を行いましたので、今回はエラーステータスをデータベースに反映します。
機能について
- データベースにある顧客リストのメールアドレス宛にメールを一括送信
- エラーリストを使って次回以降送信しないようにNotionのデータを更新
後半となるこの記事ではblastengineから取得できるエラーリストを使って、データベースにある顧客リストのメールアドレスのステータスを更新します。
ベースとなるアプリやライブラリは前回のものを使います。
ファイルの作成
今回は update.ts
というファイルを作成します。
ライブラリ読み込み
update.ts
への記述です。まず最初に必要なライブラリを読み込みます。
// dotenvを読み込み、環境変数を設定する
require('dotenv').config();
// Notionのクライアントを読み込む
import { Client } from '@notionhq/client';
// Notionから返されるページオブジェクトの型を読み込む
import { PageObjectResponse } from '@notionhq/client/build/src/api-endpoints';
// blastEngineとErrorReportを読み込む
import { BlastEngine, ErrorReport } from 'blastengine'
Notionクライアントの初期化への接続情報を作成する
.env
ファイルに定義したシークレットを使って、Notionクライアントを作成します。
// Notion APIの認証を設定
const notion = new Client({ auth: process.env.NOTION_SECRET });
blastengineの初期化
blastengine SDKを初期化します。こちらも .env
ファイルの内容を使います。
// blastEngineを初期化する
new BlastEngine(process.env.BLASTENGINE_USERID, process.env.BLASTENGINE_APIKEY);
無名関数の定義
ここからはネットワーク処理があるので、非同期処理用にasync/awaitを定義します。
// メイン処理をasync関数で囲む
(async () => {
// ここからはこの中に書いていきます
})();
blastengineのエラーレポートをダウンロード
blastengineのエラーレポートをダウンロードします。これは、2回以上配信エラーがあったメールアドレスが記録されています。
// blastEngineのエラーレポートを管理するオブジェクトを作成する
const report = new ErrorReport;
// ダウンロードができるようになるまで待つ
while (await report.finished() === false) {
// 1秒待つ
await new Promise(res => setTimeout(res, 1000));
}
// エラーレポートをダウンロードする
const results = await report.download();
エラーレポートは管理画面でも確認できます。
Notionからレコードを取得
エラーレポートに含まれているメールアドレスを使って、Notionのデータベースを検索します。
// ダウンロードしたエラーレポートからメールアドレスを取り出し、
// それらのメールが含まれるページのIDを取得する
const ary = await fetchAll(
process.env.DB_ID!,
results.map((r: any) => r.email)
);
fetchAll関数は以下のようになります。関数は (async () => {
外で問題ありません。
// Notionデータベースから未送信の情報を取得する関数
const fetchAll = async (databaseId: string, emails: string[]): Promise<string[]> => {
// データベースをクエリして、結果を取得する
const res = await notion.databases.query({
database_id: databaseId,
filter: {
// フィルタ条件は指定されたメールアドレスが含まれているエントリ
or: emails.map(email => ({
property: process.env.EMAIL_PROPERTY!,
rich_text: {
contains: email,
}
}))
}
});
// 返された結果からIDのみを取り出す
return (res.results as PageObjectResponse[]).map(row => row.id);
};
Notionデータベースのプロパティを更新する
取得できたページIDを使って、Notionデータベースを更新します。
// 取得したページのIDに対してプロパティを更新する
await updateAll(ary);
updateAll
関数は以下のようになります。これも (async () => {
外で問題ありません。
// 全ての指定されたページのプロパティを更新する関数
const updateAll = async (ary: string[]): Promise<boolean> => {
// 指定されたページIDすべてを非同期で更新する
const res = await Promise.all(ary.map(id => {
return notion.pages.update({
page_id: id,
properties: {
// 更新するプロパティはCHECKBOX_IDの値
[process.env.CHECKBOX_ID!]: {
checkbox: true,
}
}
});
}));
return true;
};
スクリプトの全体像
update.ts
の内容は以下の通りです。
// dotenvを読み込み、環境変数を設定する
require('dotenv').config();
// Notionのクライアントを読み込む
import { Client } from '@notionhq/client';
// Notionから返されるページオブジェクトの型を読み込む
import { PageObjectResponse } from '@notionhq/client/build/src/api-endpoints';
// Notion APIの認証を設定する
const notion = new Client({ auth: process.env.NOTION_SECRET });
// blastEngineとErrorReportを読み込む
import { BlastEngine, ErrorReport } from 'blastengine';
// BlastEngineのユーザIDとAPIキーを使ってblastEngineを初期化する
new BlastEngine(process.env.BLASTENGINE_USERID, process.env.BLASTENGINE_APIKEY);
// Notionデータベースから未送信の情報を取得する関数
const fetchAll = async (databaseId: string, emails: string[]): Promise<string[]> => {
// データベースをクエリして、結果を取得する
const res = await notion.databases.query({
database_id: databaseId,
filter: {
// フィルタ条件は指定されたメールアドレスが含まれているエントリ
or: emails.map(email => ({
property: process.env.EMAIL_PROPERTY!,
rich_text: {
contains: email,
}
}))
}
});
// 返された結果からIDのみを取り出す
return (res.results as PageObjectResponse[]).map(row => row.id);
};
// 全ての指定されたページのプロパティを更新する関数
const updateAll = async (ary: string[]): Promise<boolean> => {
// 指定されたページIDすべてを非同期で更新する
const res = await Promise.all(ary.map(id => {
return notion.pages.update({
page_id: id,
properties: {
// 更新するプロパティはCHECKBOX_IDの値
[process.env.CHECKBOX_ID!]: {
checkbox: true,
}
}
});
}));
return true;
};
// メイン処理をasync関数で囲む
(async () => {
// blastEngineのエラーレポートを管理するオブジェクトを作成する
const report = new ErrorReport;
// ダウンロードができるようになるまで待つ
while (await report.finished() === false) {
// 1秒待つ
await new Promise(res => setTimeout(res, 1000));
}
// エラーレポートをダウンロードする
const results = await report.download();
// ダウンロードしたエラーレポートからメールアドレスを取り出し、
// それらのメールが含まれるページのIDを取得する
const ary = await fetchAll(
process.env.DB_ID!,
results.map((r: any) => r.email)
);
// 取得したページのIDに対してプロパティを更新する
await updateAll(ary);
// 完了メッセージをログに表示する
console.log('更新完了しました');
})();
実行する
以下のようにしてコマンドプロンプトやターミナルで実行します。
npx ts-node update.ts
以下のようなメッセージが出れば更新されているはずです。
更新完了しました
Notionデータベースも更新されているはずです。
まとめ
今回はblastengineの配信エラーレポートをダウンロードして、Notionのデータベースへ反映するまでの流れを紹介しました。
Notionデータベースはメールの配信ログやメールアドレスを蓄積しておくのにぴったりです。ぜひblastengineと組み合わせてください。