WIP: actionable notifications

This commit is contained in:
estevez-dev 2020-05-17 00:44:52 +03:00
parent df94ce6180
commit 68a7080a5b
2 changed files with 61 additions and 74 deletions

View File

@ -75,7 +75,7 @@ exports.sendPushNotification = functions.https.onRequest(async (req, res) => {
} }
if(docData.deliveredCount > MAX_NOTIFICATIONS_PER_DAY) { if(docData.deliveredCount > MAX_NOTIFICATIONS_PER_DAY) {
return res.status(429).send({ return res.status(429).json({
errorType: 'RateLimited', errorType: 'RateLimited',
message: 'The given target has reached the maximum number of notifications allowed per day. Please try again later.', message: 'The given target has reached the maximum number of notifications allowed per day. Please try again later.',
target: token, target: token,
@ -99,7 +99,7 @@ exports.sendPushNotification = functions.https.onRequest(async (req, res) => {
await setRateLimitDoc(ref, docExists, docData, res); await setRateLimitDoc(ref, docExists, docData, res);
return res.status(201).send({ return res.status(201).json({
messageId: messageId, messageId: messageId,
sentPayload: payload, sentPayload: payload,
target: token, target: token,
@ -138,7 +138,7 @@ function legacyGetCurrentRateLimitsDocName() {
function legacyHandleError(res, step, incomingError) { function legacyHandleError(res, step, incomingError) {
if (!incomingError) return null; if (!incomingError) return null;
console.error('InternalError during', step, incomingError); console.error('InternalError during', step, incomingError);
return res.status(500).send({ return res.status(500).json({
errorType: 'InternalError', errorType: 'InternalError',
errorStep: step, errorStep: step,
message: incomingError.message, message: incomingError.message,
@ -156,10 +156,10 @@ async function handleRequest(req, res, payloadHandler) {
var today = getToday(); var today = getToday();
var token = req.body.push_token; var token = req.body.push_token;
if (!token) { if (!token) {
return res.status(403).send({ 'errorMessage': 'Missed token' }); return res.status(403).json({ 'errorMessage': 'Missed token' });
} }
if (token.indexOf(':') === -1) { if (token.indexOf(':') === -1) {
return res.status(403).send({'errorMessage': 'Invalid token'}); return res.status(403).json({'errorMessage': 'Invalid token'});
} }
var workerResult = payloadHandler(req); var workerResult = payloadHandler(req);
@ -189,7 +189,7 @@ async function handleRequest(req, res, payloadHandler) {
} }
if (updateRateLimits && docData.deliveredCount > MAX_NOTIFICATIONS_PER_DAY) { if (updateRateLimits && docData.deliveredCount > MAX_NOTIFICATIONS_PER_DAY) {
return res.status(429).send({ return res.status(429).json({
errorType: 'RateLimited', errorType: 'RateLimited',
message: 'You have exited the maximum number of notifications allowed per day. Please try again later.', message: 'You have exited the maximum number of notifications allowed per day. Please try again later.',
target: token, target: token,
@ -219,7 +219,7 @@ async function handleRequest(req, res, payloadHandler) {
if (debug) console.log('Not updating rate limits because notification is critical or command'); if (debug) console.log('Not updating rate limits because notification is critical or command');
} }
return res.status(201).send({ return res.status(201).json({
messageId: messageId, messageId: messageId,
sentPayload: payload, sentPayload: payload,
target: token, target: token,
@ -255,7 +255,7 @@ function handleError(res, payload, step, incomingError) {
} else { } else {
console.error('InternalError during', step, incomingError); console.error('InternalError during', step, incomingError);
} }
return res.status(500).send({ return res.status(500).json({
errorType: 'InternalError', errorType: 'InternalError',
errorStep: step, errorStep: step,
message: incomingError.message, message: incomingError.message,

View File

@ -1,33 +1,15 @@
module.exports = { module.exports = {
createPayload: function createPayload(req) { createPayload: function createPayload(req) {
let payload = { var payload = {
android: {}, android: {},
data: {}, notification: {},
fcm_options: { data: {
analytics_label: "androidV1Notification" click_action: "FLUTTER_NOTIFICATION_CLICK"
} },
}; };
let updateRateLimits = true; var updateRateLimits = true;
if (req.body.data) { 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 // Allow setting of ttl
// https://firebase.google.com/docs/reference/admin/node/admin.messaging.AndroidConfig.html#optional-ttl // https://firebase.google.com/docs/reference/admin/node/admin.messaging.AndroidConfig.html#optional-ttl
if (req.body.data.ttl) { if (req.body.data.ttl) {
@ -45,24 +27,29 @@ module.exports = {
'bodyLocKey', 'bodyLocArgs', 'titleLocKey', 'titleLocArgs', 'channelId', 'bodyLocKey', 'bodyLocArgs', 'titleLocKey', 'titleLocArgs', 'channelId',
'ticker', 'sticky', 'eventTime', 'localOnly', 'notificationPriority', 'ticker', 'sticky', 'eventTime', 'localOnly', 'notificationPriority',
'defaultSound', 'defaultVibrateTimings', 'defaultLightSettings', 'vibrateTimings', 'defaultSound', 'defaultVibrateTimings', 'defaultLightSettings', 'vibrateTimings',
'visibility', 'notificationCount', 'lightSettings', 'image' 'visibility', 'notificationCount', 'lightSettings', 'image']) {
]) {
if (req.body.data[key]) { if (req.body.data[key]) {
payload.data[key] = String(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) { if (req.body.message) {
payload.data.message = req.body.message payload.data.message = req.body.message;
if (req.body.message in ['request_location_update', 'clear_notification']) { if (req.body.message in ['request_location_update', 'clear_notification']) {
updateRateLimits = false updateRateLimits = false
} else {
payload.notification.body = req.body.message;
} }
} }
if (req.body.title) { if (req.body.title) {
payload.data.title = req.body.title payload.data.title = req.body.title
if (req.body.message in ['request_location_update', 'clear_notification']) {
updateRateLimits = false
} else {
payload.notification.title = req.body.title;
}
} }
return { updateRateLimits: updateRateLimits, payload: payload }; return { updateRateLimits: updateRateLimits, payload: payload };