SendGrid + Cloud Functionsで毎朝お天気通知してみよう


概要

Firebase Cloud Functionsと、SendGridによって毎朝お天気と祝日を通知してくれるアプリをさくっと作成してみました。

アーキテクチャ図

Firebase Cloud Functions
Firebaseによる、サーバレスにプログラムを実行してくれるサービス。今回はnode.jsで記述します。

SendGrid
クラウドベースのメール配信サービス

拝借したAPI

Firebase - プロジェクトの作成

自分のGoogleアカウントで、Firebaseコンソールから、Firebaseのプロジェクトを作成します。
今回は、設定などはデフォルトで大丈夫です。

Cloud Functionsを使用するためには、プロジェクトの料金プランをSpark(無料)からBlaze(従量課金制)に変更する必要があります。

SendGridのアカウントの作成

SendGridからアカウントを作成します。

アカウントを使用できるようになるまでは審査が必要で、使用目的や用途を書く必要があります。
自分の場合は、金曜日に登録をして月曜日に審査が通りました。

ローカルファイルとFirebaseの接続

VSCode内で空のディレクトリを開き、Firebaseの初期化を行います。
以下の公式ドキュメントのFirebase CLI をインストールするFirebase プロジェクトを初期化するを実行します。

Firebase プロジェクトを初期化するに記載のある、firebase initを実行する。
今回はCloud Functionsのみ使用するので、Cloud Functionsをセットアップする。

プロジェクトのセットアップで、先ほど作成したプロジェクトを選択する。

? Please select an option: Use an existing project
? Select a default Firebase project for this directory: //先ほど作成したプロジェクトを選択
i  Using project //先ほど作成したプロジェクト

Firebaseのプロジェクトのセットアップが完了すると、ディレクトリ内に各フォルダが作成されます。

SendGridのAPIキー取得

SendGridにログインし、Dashboard > Settings > API Keysから、Create API KeyでAPIキーを作成する。
作成した直後にAPIキーは表示されるが、その時からAPIキーは表示されないので注意。

Cloud Functionsの環境変数の設定

Cloud Functionsはターミナルから環境変数を自由に設定することができます。
後にコード内でSendGridのAPIキーを使用するために、Cloud Functionsの環境変数にSendGridのAPIキーを設定します。

firebase functions:config:set sendGrid.apikey="YOUR API KEY"

コーディング

index.js
const functions = require("firebase-functions");
const sgMail = require('@sendgrid/mail');
const admin = require('firebase-admin');
const axios = require('axios');
require('date-utils');

admin.initializeApp();

exports.sendEmailScheduler = functions
    .region('asia-northeast1')
    .pubsub
    // 毎日8時に実行
    .schedule('0 8 * * *')
    .timeZone('Asia/Tokyo')
    .onRun(async (context) => {
        try {

            // 環境変数の呼び出し
            const config = functions.config();
            // APIキーの設定
            sgMail.setApiKey(config.sendgrid.apikey);
            fromTo = "YOUR EMAIL ADREESS"

            // お天気APIの取得
            const weatherRes = await axios.get('https://weather.tsukumijima.net/api/forecast/city/130010');

            // 祝日APIの取得
            const holidayRes = await axios.get('https://holidays-jp.github.io/api/v1/2022/date.json');

            // Date → yyyy-mm-ddを変換する
            var dt = new Date();
            var formattedDt = dt.toFormat("YYYY-MM-DD");
            var japanizedDt = dt.toFormat("YYYY年MM月DD日")

            // 祝日出ない場合、ふつうの日と格納
            var holiday = typeof holidayRes.data[formattedDt] === "undefined" ? "" : "(" + holidayRes.data[formattedDt] + ")"
            var weather = weatherRes.data.forecasts[0].telop;
            var description = weatherRes.data.description.bodyText

            //メッセージの作成
            const titleText = japanizedDt + holiday;
            const messageText = "\n\n" + weather + "\n\n" + description;

            // メールに関する情報を設定
            const msg = {
                to: fromTo,
                from: fromTo,
                subject: titleText,
                text: messageText,
            };

            // メールの送信
            await sgMail.send(msg);

        } catch (error) {
            throw error;
        }
    })

パッケージインストール

ターミナル上で、

  • SendGrid用のパッケージ
  • APIを叩くためのHTTPクライアントのパッケージ
  • 日付のフォーマット用パッケージ

をインストールをする。

npm install @sendgrid/mail
npm install axios  
npm install date-utils

デプロイ

ターミナル上で、

firebase deploy --only functions

✔ Deploy complete!と表示されたらデプロイ完了!

(毎日8時に実行するのですが、稼働確認のためGCPのテストから関数を実行してみます・・・)

メールが届いた

🎉🎉🎉🎉🎉🎉🎉

宣伝

当部ではnoteにおいて、このような情報発信を行っています。

  • Flutter,Firebaseの入門者向けの情報、
  • 新規事業企画(Fintech、AIなど)
  • 研修サービス(ブロックチェーン、コンテナ開発など)
  • 新技術調査検証(Kubernetes、スマホアプリ開発、FIDO2、ローコード開発など) …etc

ご興味のある方は、ぜひ以下からご覧ください!