LoginSignup
5
2

More than 5 years have passed since last update.

Firebase FunctionsでSlack botを作ってみる

Posted at

モチベーション

Firestoreに保存してある誕生日情報をもとに、おめでとう通知をSlackにさせたかったので簡単なSlack botをfunctionsで作ってみました。
公式のnode.js用のSlackクライアントがnpmに転がっているのですが、使われている記事をみたことがなかったので試しに使ってみました。

必要なもののインストール

yarn
yarn add @slack/client

Functionsでfirebase adminを動かすために、認証情報が必要になるので、functionsの環境変数に設定しておくか、jsonファイルをfirebaseのコンソールからダウンロードしてプロジェクトに配置してください。

コード

index.ts
import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
import * as serviceAccountKey from '../serviceAccountKey.json';
import { WebClient } from '@slack/client';

admin.initializeApp({credential: admin.credential.cert(serviceAccountKey as any)});

const slack = new WebClient(functions.config().slack.api_key);

interface IUser {
    birthday: Date;
    name: string;
}

const notifySlack = async (users: IUser[]) => {
    let names = '';

    if (users.length === 1) {
        users.map(user => names += user.name + ', ');
    } else {
        names = users[0].name;
    }

    const res = await slack.chat.postMessage(
        {
            channel: functions.config().slack.channel,
            text: "今日は" + names + "が誕生日!",
        }
    )

    console.log(res);
}

const aggregateUsers = (snapshot: FirebaseFirestore.QuerySnapshot): IUser[] => {
    const today = new Date();
    const users: IUser[] = new Array();

    snapshot.docs.forEach(doc => {
        const birthday: Date = doc.data().birthday.toDate();
        if(birthday.getDate() === today.getDate() && birthday.getMonth() === today.getMonth()){
            users.push(
                {
                    birthday: doc.data().birthday,
                    name: doc.id,
                }
            );
        };
    });

    return users;
}

export const checkBirthday = functions.https.onRequest((req, resp) => {
    const ref = admin.firestore().collection('users');

    ref.get()
    .then(snapshot => {
        const users = aggregateUsers(snapshot);

        users.length === 0 ?
            resp.send('ok')
            :
            notifySlack(users)
                .then(() => resp.send('ok'))
                .catch((e) => resp.send('error:' + e))
    })
    .catch((e) => {
        resp.send('error:' + e);
    });
});

上記のコードでデプロイして、関数を発火させるためのURLを発行します。

cronの設定

毎日、誕生日に該当する人がいないかチェックしたいので、cron-job.orgに発行したURLを設定してcronを回します。
ちなみに、slack通知させることは外部アクセスにあたるのでfirebaseの無料枠ではできません。
firebaseのプランはBlazeプランにしましょう。

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2