Help us understand the problem. What is going on with this article?

FirebaseからGoogleSpreadSheetに書き込みをし、その更新をメール通知する

はじめに

当記事は、FirebaseのCloudFunctionからGoogleSpreadSheetにFirestoreへ新規追加されたデータ内容の書き込みをし、その更新をメール通知する実装についての備忘録です。

CloudFunctionの導入は省略しますが、宜しければこちらを参考にしてください。

FirebaseからGoogeleSpreadSheetに書き込みを行う

大まかな手順
・FIrebaseの設定
・GoogeleSpreadSheet APIの取得
・CloudFunctionの実行

FIrebaseの設定

FirebaseからGoogleSpreadSheetに書き込みを許可するために、
幾つかデフォルトの設定から変更をする必要があります。

①Firebaseコンソールから「プロジェクトの設定」(歯車のボタン)をクリック

②「サービスアカウント」のタブをクリック

③その他のサービスアカウントの項にある、Googleサービスアカウントへのリンクをクリック

④名前の項が「App Engine default service account」のタブの、プロジェクトID@appspot.gserviceaccount.com をコピー

⑤書き込みたいスプレッドシートを開き、右上の「共有」ボタンをクリックして表示されたダイアログの「ユーザーやグループを追加」に先ほどコピーした、プロジェクトID@appspot.gserviceaccount.com を入力

GoogeleSpreadSheet APIの取得

①GoogleCloudPlatformのナビゲージョンメニュー(左上のハンバーガーボタン)から「APIとサービスをクリック」

②ヘッダーの検索欄から「Google Sheets API」を探し、利用するプロジェクト名と一致しているか確認した上で、APIを有効にします

CloudFunctionの実行

①プロジェクトの「functions」のディレクトリへ移動
※以上のディレクトリからのみ、CloudFunctionはデプロイ出来ます

②ターミナルで「googleapis」をnpm install

$ npm install googleapis

②index.jsにコードを書いていく

index.js
const functions = require("firebase-functions");
//npm installしたgoogleAPIを宣言
const googleAPI = require("googleapis");

exports.appendSpreadSheet = functions
  .region("asia-northeast1")
  //この実装では、Cloud Firestoreの「hoge」というコレクションに値が追加されたら、スプレッドシートに書き込みをします
  .firestore.document("hoge/{hogeId}")
  .onCreate((snap, context) => {
    const foo = snap.data();
    googleAPI.auth
      .getClient({
        scopes: ["https://www.googleapis.com/auth/spreadsheets"],
      })
      .then((auth) => {
        const sheets = google.sheets("v4");
        sheets.spreadsheets.values.append({
          auth,
         //シートのURLの https://docs.google.com/spreadsheets/Idはここの部分/edit#gid=0
          spreadsheetId: "xxxxxxxxx",
          //書き込み先のシート名
          range: "書き込むシートの名前",
          //セル範囲
          //公式を参照→ https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/append?hl=ja#InsertDataOption
          valueInputOption: "RAW",
          insertDataOption: "INSERT_ROWS",
          resource: {
            values: [
              [
                //ドキュメントキー
                hoge.hogeId,
                //書き込みたいドキュメントの中身
                foo.name,
                foo.age,
              ],
            ],
          },
        });
      });
  });

以上を記述した後、functionをデプロイすることで、
任意のデータベースに値が追加(あるいは変更などでも実装可能)される度に、スプレッドシートにデータの書き込みがされます。

メール通知を加える

大まかな手順
・Gmailのセキュリティーレベルを下げる
・nodemailerのnpm install
・環境変数の設定
・CloudFunctionの実行

Gmailのセキュリティーレベルを下げる

①Googleアカウント内の安全性の低いアプリのアクセスにて、安全性の低いアプリの許可:有効にする。

②メール送受信に利用するGoogleアカウントでログインした上で、Gmailアカウントへのアクセス許可する。

nodemailerのnpm install

①ターミナルで「nodemailer」をnpm install

$ npm install nodemailer

環境変数の設定

①ターミナルで下記コマンドを打つ

firebase functions:config:set gmail.email="xxxxxxxxxx@gmail.com" gmail.password="xxxxxxxxxx"

以上を設定することで、安全にメールアドレスとパスワードをファイル上で変数定義出来ます。(この例の場合、emailならば、functions.config().gmail.emailで呼び出し)

CloudFunctionの実行

①index.jsに追記

index.js
const functions = require("firebase-functions");
const googleAPI = require("googleapis");
//npm installしたnodemailerと環境変数内のアドレスとパスワードを宣言
const nodemailer = require("nodemailer");
const gmailEmail = functions.config().gmail.email;
const gmailPassword = functions.config().gmail.password;
//送信するGmailアドレスの設定
const mailTransport = nodemailer.createTransport({
  host: "smtp.gmail.com",
  port: 465,
  secure: true,
  auth: {
    user: gmailEmail,
    pass: gmailPassword
  }
});

exports.appendSpreadSheet = functions
  .region("asia-northeast1")
  //この実装では、Cloud Firestoreの「hoge」というコレクションに値が追加されたら、スプレッドシートに書き込みをします
  .firestore.document("hoge/{hogeId}")
  .onCreate((snap, context) => {
    const foo = snap.data();
    googleAPI.auth
      .getClient({
        scopes: ["https://www.googleapis.com/auth/spreadsheets"],
      })
      .then((auth) => {
        const sheets = google.sheets("v4");
        sheets.spreadsheets.values.append({
          auth,
          spreadsheetId: "xxxxxxxxx",
          range: "書き込むシートの名前",
          valueInputOption: "RAW",
          insertDataOption: "INSERT_ROWS",
          resource: {
            values: [
              [
                //ドキュメントキー
                hoge.hogeId,
                //書き込みたいドキュメントの中身
                foo.name,
                foo.age,
              ],
            ],
          },
        });
      }).then(() => {
        let mailOptions = {
          from: gmailEmail,
          to: gmailEmail,
          subject: "メールタイトル",
          text: "メール本文"
        };
        mailTransport.sendMail(mailOptions, (err, info) => {
          if (err) {
            console.error(err);
            return;
          }
          console.log("success");
        });
      });
  });

以上、追記した内容をデプロイ後、Firestoreに値が追加される度に、メール通知がされます。
もしメールが届かない場合はCloudFunctionのログを読んだ上で、Googleアカウントのセキュリティのブロックを疑ってみると良いかもしれません。

おわりに

私が所属するチームは少数なので、作業を自動化することで、ヒューマンエラーを減らしたり、捻出した時間を他の作業に割けるのでとても助かりました。

こちらの記事を参考にさせていただきました。ありがとうございます!
スプレッドシートとの連携 
メールの送信 
Gmailのセキュリティ

shotashimura
2019年4月よりプログラミングを始めました!
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした