Cloud Functionsでメール(Gmail)を送信する方法
Cloud Functionsの実行時にメールを送信する場合、通常は有料プランでしかメールを送信できないようですが、Gmailであれば無料(Spark)プランであってもメールを送信することができます。
目次
- Cloud Functionsの環境構築
- nodemailerプラグインのインストール
- 環境変数の設定
- Functionsの作成(コード)
- デプロイ
- デプロイ後のFunction削除
- 安全性の低いアプリのアクセス許可
- 余談
- 参考リンク
Cloud Functionsの環境構築
Cloud Functionsの環境を用意するには、プロジェクトのホームディレクトリに移動後、ターミナルから以下のコマンドを実行します。
firebase init functions
nodemailerプラグインのインストール
メールの送信には「nodemailer」を使用します。
functionsディレクトリに移動後、インストールを実行。
cd functions
npm install nodemailer --save
環境変数の設定
メールを送信するためにはGmailのメールアドレスとパスワードが必要になりますが、ソースコードに直接記述するのはセキュリティ的によろしくないので、ターミナルから以下のコマンドを実行して、Forebaseの環境変数に格納します。
firebase functions:config:set gmail.email="xxxxxxxxxx@gmail.com" gmail.password="xxxxxxxxxx"
格納した環境変数を確認する場合は「get」。
firebase functions:config:get
Functionsの作成(コード)
functionsディレクトリ配下の「index.js」に以下のコードを追記します。
const functions = require('firebase-functions');
const nodemailer = require('nodemailer')
const gmailEmail = functions.config().gmail.email
const gmailPassword = functions.config().gmail.password
const mailTransport = nodemailer.createTransport({
service: 'gmail',
auth: {
user: gmailEmail,
pass: gmailPassword
}
})
exports.createProduct = functions
.region('asia-northeast1')
.firestore
.document('products/{productId}')
.onCreate((snap, context) => {
let mailOptions = {
from: gmailEmail,
to: gmailEmail,
subject: 'sample',
text: 'Hello World!'
}
mailTransport.sendMail(mailOptions, (err, info) => {
if (err) {
console.error(err)
return
}
console.log('success')
})
});
上記のコードは、Firestoreのコレクション「products」にデータが追加(onCreate)された時に実行される関数になります。
格納したFirebaseの環境変数には functions.config() でアクセス可能です。
Cloud Functionsはデフォルトのリージョンが「us-central1」となっているので、region('asia-northeast1') で切り替えています。
デプロイ
作成した関数をCloud Functionsにデプロイするには、ターミナルから以下のコマンドを実行します。
firebase deploy --only functions
デプロイ後のFunction削除
一度作成してしまった関数を削除したい場合は、ターミナルから以下のコマンドを実行します。
firebase functions:delete createProduct
安全性の低いアプリのアクセス許可
最後にGoogleアカウントのセキュリティ管理にアクセスして、安全性の低いアプリのアクセスを有効に設定します。
セキュリティが弱くなってしまうので、実際に試す際はテスト用のアカウントを用意した方がいいと思います。
実際に実行してみてメールが送信されれば成功。
上手くいかない場合は、FirebaseのコンソールからCloud Functionsのログを確認して、console.log()などで出力した情報からエラーの原因を特定します。
余談
日次や月次のバッチ処理をCloud Functionsで実装できないかと思いましたが、それはどうやら有料(Pub/Subトリガー?)のようです。