Firebaseで拡張機能とSendGridを使って自動でメールを送信するための設定方法まとめ

# はじめに

Firebaseを使って特定のドキュメントが作成された時に、関連づけられたユーザーにメールを送信する機能を実装する機会がありました。

Firebaseには、**Trigger Email**という拡張機能が存在することは知っていたのですが、SMTPの設定など難しそうな単語が並んでいたので敬遠していました。

しかし、上記の機能の実装の必要性に迫られ、SendGridを使ってSMTPプロバイダーの設定を行い、その情報を元にTrigger Email拡張機能を設定してみることにしました。

今回は、Trigger Email拡張機能を使用可能にするまでの、SendGridやFirebaseでの設定方法を、将来の自分への忘備録としてまとめておこうと思います。

# SendGridの設定

SendGridのページを開きます。事前にアカウントの作成とSenderの作成を行なっておいてください。

サイドメニューから、Email API -> Integration Guideを選択します。

そして、SMTP Relayを選択します。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/dfec89b1-bc39-67ed-6ac3-132cbb88c23a.png)


My First API Key nameにプロジェクト名を入力します。

プロジェクト名を入力したら、**Create API Key**をクリックします。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/bc4f3977-727a-aeb5-e70c-16253f8d6b22.png)

表示されているAPI Keyとポート番号を組み合わせて、次の文字列を作成します。

```
smtps://apikey:YOUR_GENERATED_KEY@smtp.sendgrid.net:PORT_NUMBER
```

**Next: Verify Integration**をクリックします。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/b1ffac26-de0c-ccc6-fb1d-0efa35c6ef72.png)

下記で、Firebaseの設定を行ったあと`mail`コレクションにドキュメントを作成して`to`に設定したメールアドレス宛にメールが届くことを確認したあとに**Verify Integration**をクリックしてください。

正しくメールが送信された状態で、**Verify Integraiton**をクリックするとトップページに遷移します。

![名称未設定のデザイン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/fac6980e-4182-41ce-33bf-962e5f4bcf3d.png)


# Firebaseの設定

Firebaseコンソールにて、Trigger Email拡張機能をインストールします。

https://extensions.dev/extensions/firebase/firestore-send-email

## Trigger Email拡張機能のインストール手順

まず、FirebaseコンソールのExtensionsページで、Trigger Emailのインストールボタンをクリックします。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/baf1fba7-4e70-6f2d-0f8f-403f1b9c36e9.png)

お支払い情報と利用状況の確認画面にて表示される内容を確認し、次へをクリックします。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/4c19145c-b9ce-4748-43c0-82292955bc37.png)

もし、Firebase Functionsのデプロイがまだ完了していない場合は、**Cloud Functions**と**Artifact Registry**がリストに表示されます。この状態で有効にするをクリックした場合に失敗する可能性があります。なので、あらかじめ最初のデプロイを行なっておくことをお勧めします。その場合は**Artifact Registry**のみ自動的に有効化されます。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/1797f1bf-db99-8519-b9c7-ff9008efcf5c.png)

デプロイした場合は、次のように**Cloud Functions**のみリストに表示されます。**有効にする**をクリックします。

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/347a8d2a-f55b-a4e8-fa79-8041e9c30e3f.png)

次へが押せるようになったら次へをクリックします。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/05d5fd1c-d6df-aa50-86d8-f1938871808c.png)

この機能に付与されたアクセス権を確認ページにて表示されている説明をきちんと読み、内容を確認した上で次へをクリックします。

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/3a6ee0de-0c86-476e-7e0b-9bac82229ffe.png)

拡張機能を構成ページにて、必要な項目を入力します。

![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/1dbe682c-5d9b-cbe8-fecd-de4886c05754.png)

必要な入力が全て終了したら**拡張機能をインストール**をクリックします。

インストールが完了次第、設定したメール用のコレクションにドキュメントが追加されるとSendGridで設定した内容に基づいてメールが送信されます。

![13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/f5d854f0-5f53-5679-420e-6a9fef7c1b9d.png)

以下では、拡張機能を構成ページにて入力する各項目について解説していきます。

## Cloud Functions location

この拡張機能で作成される関数が配置されるロケーションを選択します。通常はCloud Firestoreと同じロケーションを選択することが好ましいです。

例えば、Firestoreを`asia-northeast1`を選択している場合は、ここでも`Tokyo (asia-northeast1)`を選択します。

## SMTP connection URI

先ほどSendGridのサイトで取得したAPIキーを元に作成した文字列をここで入力します。

```
smtps://apikey:SendGridで生成されたAPIキー@smtp.sendgrid.net:465
```

## SMTP password

SendGridのページでAPIキーを生成した際にパスワードも表示されています。そのパスワードをここに入力しましょう。
入力が完了したら、**シークレットを作成**をクリックします。

## Email documents collection

コレクションのパスを入力します。ここで指定されたコレクションへドキュメントが作成されるこの拡張機能で生成された関数がトリガーされます。

デフォルトの`mail`か、公式ドキュメントで使用されている`email`を入力します。

## Default FROM address

返信元のアドレスを入力します。ここで入力するメールアドレスは、SendGridで**Sender**を作成した際に登録した**From Email Address**を指定します。

![名称未設定のデザイン.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577119/52b7f5a6-86ea-35bf-3380-98d4813568e9.png)


**From Name**も使用して次のように送信者名を指定することも可能です。

```
Friendly Firebaser <foobar@example.com>
```

## Default REPLY-TO address

返信先として使用されるメールアドレスを入力します。この値は、トリガーされる際に作成されるドキュメントに`replyTo`フィールドが存在しない場合に使用されます。

ここで入力する値もで、先ほどと同じようにSendGridで**Sender**を作成する際に指定した**Reply To**を指定します。

## Users collection

メール送信のトリガーに使われる`mail（デフォルト）`コレクションのドキュメントを作成する際に、`toUids`、`ccUids`、そして`bccUids`フィールドにこの`Usersコレクション`ドキュメントIDを指定することで、直接メールアドレスを`mail`コレクションのドキュメントに指定することなくメールの送信を行うことができるようになります。この拡張機能がUsersコレクションの内容を取得して、その値に応じてメールを送信してくれるのです。

この機能は使用しない場合は空の状態で大丈夫です。

## Templates collection

ドキュメントの`template`フィールドを設定すると、このコレクションに存在するドキュメントを使用してメールの内容を構築することができます。

例えば、Templates collectionに`templates`を設定した場合、`templates`コレクションのドキュメントのidを`template.name`に指定します。
その`templates`コレクションのドキュメントでは、ハンドルバーテンプレートを使用することができます。

```
[welcome]: {
    subject: "{{name}}さんへ",
    text: "いつもご利用いただきありがとうございます。"
}
```

上記のドキュメントidである`welcome`を`mail`コレクションのドキュメントの`template`の`name`に`welcome`を指定し、`template.data.name`に`田中太郎`を指定することで、`田中太郎さんへ`という件名のメールを作成することができます。

```
{
    to: "example@example.com",
    template: {
        name: "welcome",
        data: {
            name: "田中太郎",
        }
    }
}
```

今回は`templates`を入力します。

## イベントを有効にする

この拡張機能に応答するカスタムイベントハンドラを作成することができます。詳しくはこちらをご参照ください。

https://firebase.google.com/docs/extensions/install-extensions?authuser=0&hl=ja&platform=console#eventarc

この項目はオプションです。僕は今回使用しませんでした。

# mailコレクションのドキュメントのスキーマ

メールのドキュメントは次のスキーマになっています。

```
{
    from: string | undefined;
    to: string | string[];
    cc: string | string[] | undefined;
    bcc: string | string[] | undefined;
    replyTo: string | undefined;
    headers: { [string]: string } | undefined;
    message: { 
        "subject": string | undefined;
        "text": string | undefined;
        "html": string | undefined;
        ...
    };
}
```

`from`と`replyTo`はカスタム属性になっています。これらのフィールドに指定する値は、SendGridで検証されている必要があるため、必ずSenderに登録されている値を使用してください。そうでない場合は`550`のエラーコードが返される可能性があります。

`message`に指定する値はNodemailerの**Message Configuration**で紹介されているフィールドの値を指定することができます。しかし、`message`に含まれた`from`や`replyTo`などの値はこのドキュメントの`from`や`replyTo`によって上書きされるため無視されますのでご注意ください。

https://nodemailer.com/message/

# templatesコレクションのドキュメントのスキーマ

`text`や`html`フィールド内では、`{{変数名}}`を使用して変数を挿入することができます。ここで指定する変数は、`mail`コレクションのドキュメントを作成する際に`template.data`に`[key: string]: string`を設定することで渡すことができます。

```
[welcome]: {
    subject: string | undefined;
    text: string | undefined;
    html: string | undefined;
    attachments: {
        filename: string;
        path: string;
    }[] | undefined;
}
```

# まとめ

この拡張機能を使うと、例えば特定のコレクションにドキュメントが作成された際にトリガーされるバックグラウンド関数を定義し、その関数ないで`mail`コレクションにドキュメントを追加することでユーザーにお知らせを配信することができるようになります。

ぜひ、SendGridとTrigger Email拡張機能を使ってユーザーにとって優しいアプリケーションを実装してみてください。

# 参考にした記事

https://medium.com/firebase-developers/firebase-extension-trigger-email-5802800bb9ea

https://nodemailer.com/message/

https://firebase.google.com/docs/extensions/official/firestore-send-email

https://firebase.google.com/docs/extensions/official/firestore-send-email/templates

https://handlebarsjs.com/