TL;DR

  • メンテナンス情報を Firebase Cloud Fire Store から取得する
  • uptimerobot の Webhook を使う
  • Firebase functions で uptimerobot からの webhook を受け取る
  • Firebase functions で Firebase Cloud Fire Store を書き換える

Firebase Cloud Fire Store を使う

firestore.js

import Firebase from 'firebase'
import 'firebase/firestore'
let config = {}
if (process.env.STAGE === 'staging' || process.env.STAGE === 'develop' || process.env.STAGE === 'local') {
config = {
apiKey: '',
authDomain: 'easyuploader-web-stg.firebaseapp.com',
databaseURL: 'https://easyuploader-web-stg.firebaseio.com',
projectId: 'easyuploader-web-stg',
storageBucket: 'easyuploader-web-stg.appspot.com',
messagingSenderId: '1029528151776',
appId: '1:1029528151776:web:ba68efd8003542a10fd285'
}
}
if (process.env.STAGE === 'production') {
config = {
apiKey: '',
authDomain: 'easyuploader-web.firebaseapp.com',
databaseURL: 'https://easyuploader-web.firebaseio.com',
projectId: 'easyuploader-web',
storageBucket: 'easyuploader-web.appspot.com',
messagingSenderId: '940122739680',
appId: '1:940122739680:web:8b6d89ef3d3ac20a841185'
}
}
if (process.env.STAGE === 'free') {
config = {
apiKey: '',
authDomain: 'easyuploader-free.firebaseapp.com',
databaseURL: 'https://easyuploader-free.firebaseio.com',
projectId: 'easyuploader-free',
storageBucket: 'easyuploader-free.appspot.com',
messagingSenderId: '816447004806',
appId: '1:816447004806:web:4b3ca4d405e8cfa66bb107',
measurementId: 'G-JGTVDZE5MY'
}
}
const firebaseApp = Firebase.initializeApp(config, 'exercise-vue')
const firestore = firebaseApp.firestore()
export default firestore

App.vue

<script>
import firestore from './firestore'
const initRef = firestore.collection('init')
export default {
name: 'EasyUploader',
created () {
initRef.get().then(querySnapshot => {
querySnapshot.forEach(doc => {
const initObj = doc.data()
this.initObj.isMaintenance = initObj.maintenance
this.initObj.message = '【お知らせ】' + initObj.message
})
})
}
}
</script>

uptimerobot webhook

uptimerbot は無料で使える死活監視 SaaS で、アラートに webhook が使える。

uptimerobot.com

そして、指定した URL にクエリパラメータとして下記の情報が付与される

*monitorID* (the ID of the monitor)
*monitorURL* (the URL of the monitor)
*monitorFriendlyName* (the friendly name of the monitor)
*alertType* (1: down, 2: up, 3: SSL expiry notification)
*alertTypeFriendlyName* (Down or Up)
*alertDetails* (any info regarding the alert -if exists-)
*alertDuration* (in seconds and only for up events)
*alertDateTime* (in Unix timestamp)
*monitorAlertContacts* (the alert contacts associated with the alert in the format of 457;2;[email protected] -alertContactID;alertContactType, alertContactValue)
*sslExpiryDate* (only for SSL expiry notifications)
*sslExpiryDaysLeft* (only for SSL expiry notifications)

Firebase Functions

個人開発の雑書きですが、やりたいことはなんとなく分かると思います。

const functions = require('firebase-functions')
const admin = require('firebase-admin')
admin.initializeApp(functions.config().firebase)
const firestore = admin.firestore()
// eslint-disable-next-line consistent-return
exports.uptimerobot = functions.https.onRequest((req, res) => {
const project = process.env.GCLOUD_PROJECT
const alertType = req.query.alertType
const monitorID = req.query.monitorID
console.log(`project: ${project}`)
console.log(`alertType: ${alertType}`)
console.log(`monitorID: ${monitorID}`)
const docGetFileProblem = {
maintenance: false,
message: '現在ファイルの参照ができない問題が発生しています'
}
const docGetFileSolved = {
maintenance: false,
message: ''
}
const docBasicFunctionProblem = {
maintenance: true,
message: '現在アップロードすることができません'
}
const docBasicFunctionSolved = {
maintenance: false,
message: ''
}
const docUploadProblem = {
maintenance: true,
message: ''
}
const docUploadSolved = {
maintenance: false,
message: ''
}
let docID
// staging
if (project === 'easyuploader-web-stg') {
docID = 'RA0EBeoUw0jZwxV9mGPR'
}
// free
if (project === 'easyuploader-free') {
docID = 'hwWuR9Q5Gs7KJ9MKRrkr'
}
// production
if (project === 'easyuploader-web') {
docID = 'NKqRdtrdiNBJSrYmQT5b'
}
const initRef = firestore.collection('init').doc(docID)
// down
if (alertType === '1') {
// ファイル参照
if (monitorID === '784159295') {
return initRef.update(docGetFileProblem)
// eslint-disable-next-line promise/always-return
.then(() => {
res.status(200).send('ok')
})
.catch((error) => {
console.error('Error updating document: ', error)
})
}
// 基本機能
if (monitorID === '783009626') {
return initRef.update(docBasicFunctionProblem)
// eslint-disable-next-line promise/always-return
.then(() => {
res.status(200).send('ok')
})
.catch((error) => {
console.error('Error updating document: ', error)
})
}
// アップロード
if (monitorID === '784152180') {
return initRef.update(docUploadProblem)
// eslint-disable-next-line promise/always-return
.then(() => {
res.status(200).send('ok')
})
.catch((error) => {
console.error('Error updating document: ', error)
})
}
}
// up
if (alertType === '2') {
// ファイル参照
if (monitorID === '784159295') {
return initRef.update(docGetFileSolved)
// eslint-disable-next-line promise/always-return
.then(() => {
res.status(200).send('ok')
})
.catch((error) => {
console.error('Error updating document: ', error)
})
}
// 基本機能
if (monitorID === '783009626') {
return initRef.update(docBasicFunctionSolved)
// eslint-disable-next-line promise/always-return
.then(() => {
res.status(200).send('ok')
})
.catch((error) => {
console.error('Error updating document: ', error)
})
}
// アップロード
if (monitorID === '784152180') {
return initRef.update(docUploadSolved)
// eslint-disable-next-line promise/always-return
.then(() => {
res.status(200).send('ok')
})
.catch((error) => {
console.error('Error updating document: ', error)
})
}
}
})