diff --git a/functions/index.js b/functions/index.js index 71f7db3..c60c20b 100644 --- a/functions/index.js +++ b/functions/index.js @@ -2,6 +2,7 @@ const functions = require('firebase-functions'); const admin = require('firebase-admin'); + admin.initializeApp(); var db = admin.firestore(); @@ -9,7 +10,7 @@ var db = admin.firestore(); const MAX_NOTIFICATIONS_PER_DAY = 150; exports.sendPushNotification = functions.https.onRequest(async (req, res) => { - console.log('Received payload', req.body); + if (debug()) console.log('Received payload', req.body); var today = getToday(); var token = req.body.push_token; var ref = db.collection('rateLimits').doc(today).collection('tokens').doc(token); @@ -48,7 +49,7 @@ exports.sendPushNotification = functions.https.onRequest(async (req, res) => { } } - console.log('Notification payload', JSON.stringify(payload)); + if (debug()) console.log('Notification payload', JSON.stringify(payload)); var docExists = false; var docData = { @@ -89,7 +90,7 @@ exports.sendPushNotification = functions.https.onRequest(async (req, res) => { return handleError(res, 'sendNotification', err); } - console.log('Successfully sent message:', messageId); + if (debug()) console.log('Successfully sent message:', messageId); await setRateLimitDoc(ref, docExists, docData, res); @@ -105,10 +106,10 @@ exports.sendPushNotification = functions.https.onRequest(async (req, res) => { async function setRateLimitDoc(ref, docExists, docData, res) { try { if(docExists) { - console.log('Updating existing doc!'); + if (debug()) console.log('Updating existing doc!'); await ref.update(docData); } else { - console.log('Creating new doc!'); + if (debug()) console.log('Creating new doc!'); await ref.set(docData); } } catch(err) { @@ -150,4 +151,8 @@ function getRateLimitsObject(doc) { remaining: (MAX_NOTIFICATIONS_PER_DAY - doc.deliveredCount), resetsAt: new Date(d.getFullYear(), d.getMonth(), d.getDate()+1) }; +} + +function debug() { + return false; } \ No newline at end of file diff --git a/functions/payloader.js b/functions/payloader.js new file mode 100644 index 0000000..5ff1874 --- /dev/null +++ b/functions/payloader.js @@ -0,0 +1,70 @@ +module.exports = { + createPayload: function createPayload(req) { + let payload = { + android: {}, + data: {}, + fcm_options: { + analytics_label: "androidV1Notification" + } + }; + let updateRateLimits = true; + + if(req.body.data){ + + // Handle the web actions by changing them into a format the app can handle + // https://www.home-assistant.io/integrations/html5/#actions + if(req.body.data.actions) { + for (let i = 0; i < req.body.data.actions.length; i++) { + const action = req.body.data.actions[i]; + if(action.action){ + payload.data["action_"+(i+1)+"_key"] = action.action + } + if(action.title) { + payload.data["action_"+(i+1)+"_title"] = action.title + } + if(action.uri){ + payload.data["action_"+(i+1)+"_uri"] = action.uri + } + } + } + + // Allow setting of ttl + // https://firebase.google.com/docs/reference/admin/node/admin.messaging.AndroidConfig.html#optional-ttl + if(req.body.data.ttl){ + payload.android.ttl = req.body.data.ttl + } + + // https://firebase.google.com/docs/reference/admin/node/admin.messaging.AndroidConfig.html#optional-priority + if(req.body.data.priority){ + payload.android.priority = req.body.data.priority + } + + // https://firebase.google.com/docs/reference/admin/node/admin.messaging.AndroidNotification.html + for (const key of [ + 'icon', 'color', 'sound', 'tag', 'clickAction', + 'bodyLocKey', 'bodyLocArgs', 'titleLocKey', 'titleLocArgs', 'channelId', + 'ticker', 'sticky', 'eventTime', 'localOnly', 'notificationPriority', + 'defaultSound', 'defaultVibrateTimings', 'defaultLightSettings', 'vibrateTimings', + 'visibility', 'notificationCount', 'lightSettings', 'image' + ]) { + if(req.body.data[key]){ + payload.data[key] = String(req.body.data[key]) + } + } + } + + // Always put message, title, and image in data so that the application can handle creating + // the notifications. This allows us to safely create actionable/imaged notifications. + if(req.body.message) { + payload.data.message = req.body.message + if(req.body.message in ['request_location_update', 'clear_notification']) { + updateRateLimits = false + } + } + if(req.body.title) { + payload.data.title = req.body.title + } + + return { updateRateLimits: updateRateLimits, payload: payload }; + } +} \ No newline at end of file