webpush.sendNotification - NotificationEvent.notification.data null - node.js

Setup
Operating System: Linux
Node Version: 10.15.3
web-push Version: 3.3.4
[X] Chrome
[ ] Firefox
[ ] Opera for Android
[ ] Samsung Internet Browser
[ ] Other
Chrome: Version 74.0.3729.131 (Official Build) (64-bit)
Problem
I am trying to implement example step 5.2 from google pwa lab
If I push a notification from my node/main.js script I am getting the visual notification on my screen. If I click the notification I can observe from the console the following message:
Uncaught TypeError: Cannot read property 'primaryKey' of null
at sw.js:30
If I check the content of the NotificationEvent.notification.data object it is null.
Expected
If I click the notification sent from my node server I should be able to see the data from the NotificationEvent.notification object.
Features Used
[x] VAPID Support
[ ] GCM API Key
[x] Sending with Payload
Example / Reproduce Case
This is my node/main.js that is in charge of the web push notifications.
const webPush = require('web-push');
const pushSubscription = {
endpoint: 'https://fcm.googleapis.com/fcm/send/flcWNQgYeVw:APA91bHgAC5M-WeyN5RNdSprIDUalAxSMznny3-QwPf2T8whtWwmtZ6Q546Pry-JCZqjSh9bbEIS778lJD7Hq-t4KLS35X6-T7dJGCnc_ECzKvsdOAQ50wlzQ5Tcm1WNvgOOwXV',
expirationTime: null,
keys: {
p256dh: 'BL-Rz9Nejsd7ipsYQsQ9YB6tUc-qldkBg28y7G9LBFGdKe52sSeF0FStiKmdBp5BRFf3HazlOICBAVnY',
auth: 'hOPxUEqXsdfFjB-MmFxaTw'
}
};
// TODO 4.3a - include VAPID keys
const vapidPublicKey = 'MY VAPID PUBLIC KEY';
const vapidPrivateKey = 'MY VAPID PRIVATE KEY';
const payload = 'Here is a payload!';
const options = {
//gcmAPIKey: 'NOT IN USE',
TTL: 60,
vapidDetails: {
subject: 'mailto: myemail#gmail.com',
publicKey: vapidPublicKey,
privateKey: vapidPrivateKey
},
contentEncoding: 'aes128gcm'
};
webPush.sendNotification(
pushSubscription,
payload,
options
).catch( error => {
console.log(error);
}) ;
This is the code from my service worker that handles the notifications:
self.addEventListener('notificationclose', event => {
console.log(event);
const notification = event.notification;
const primaryKey = notification.data.primaryKey;
console.log('Closed notification: ' + primaryKey);
});
self.addEventListener('notificationclick', event => {
const notification = event.notification;
console.log(notification.data);
const primaryKey = notification.data.primaryKey;
const action = event.action;
if (action === 'close') {
notification.close();
} else {
event.waitUntil(
clients.matchAll().then(clis => {
const client = clis.find(c => {
return c.visibilityState === 'visible';
});
if (client !== undefined) {
client.navigate('samples/page' + primaryKey + '.html');
client.focus();
} else {
// there are no visible windows. Open one.
clients.openWindow('samples/page' + primaryKey + '.html');
notification.close();
}
})
);
}
self.registration.getNotifications().then(notifications => {
notifications.forEach(notification => {
notification.close();
});
});
});
self.addEventListener('push', event => {
let body;
if (event.data) {
body = event.data.text();
} else {
body = 'Default body';
}
const options = {
body: body,
icon: 'images/notification-flat.png',
vibrate: [100, 50, 100],
data: {
dateOfArrival: Date.now(),
primaryKey: 1
},
actions: [
{action: 'explore', title: 'Go to the site',
icon: 'images/checkmark.png'},
{action: 'close', title: 'Close the notification',
icon: 'images/xmark.png'},
]
};
event.waitUntil(
clients.matchAll().then(c => {
console.log(c);
if (c.length === 0) {
// Show notification
self.registration.showNotification('Push Notification', options);
} else {
// Send a message to the page to update the UI
console.log('Application is already open!');
}
})
);
});
Other
I have tried changing the contentEncoding from aesgmc to aes128gcm but I am still getting the same error.
If I run the web-push command I see the same error

Related

Autocomplete slash command appear only one admin

Description
I created slash command bot with bot, applications.commands scopes. And create slash command for guild, and command not showed so I create commands as application scope. And still not showing
I tried to kick out my bot and re enter url but not worked...
What is the solution plz! Thank you
Steps to Reproduce
const serverless = require("serverless-http");
const express = require("express");
const app = express();
const { CreateRateUseCase } = require("./core/usecase/createRateUseCase");
const nacl = require("tweetnacl");
const getRawBody = require("raw-body");
const { DiscordBot } = require("./discordBot");
// const { verifyKeyMiddleware } = require("discord-interactions");
require("dotenv").config({ path: `./.env.${process.env.NODE_ENV}` });
app.post(
"/interactions",
// verifyKeyMiddleware(process.env.DISCORD_PUBLIC_KEY),
async (req, res, next) => {
try {
console.log(`req : `);
console.log(req);
console.log(`body ${req.body} ${JSON.stringify(req.body)}`);
const rawBody = await getRawBody(req);
console.log(`rawBody ${rawBody} ${typeof rawBody}`);
const body = JSON.parse(rawBody);
if (
process.env.NODE_ENV === "dev" ||
process.env.NODE_ENV === "production"
) {
const signature = req.get("X-Signature-Ed25519");
console.log(`signature ${signature}`);
const timestamp = req.get("X-Signature-Timestamp");
console.log(`timestamp ${timestamp}`);
const isVerified = nacl.sign.detached.verify(
Buffer.from(timestamp + rawBody),
Buffer.from(signature, "hex"),
Buffer.from(process.env.DISCORD_PUBLIC_KEY, "hex")
);
console.log(`isVerified ${isVerified}`);
if (!isVerified) {
console.log("Failed verification");
return res.status(401).end("invalid request signature");
}
if (body.type === 1) {
console.log("Handling validation test request");
return res.status(200).send({ type: 1 });
}
}
if (body.type === 2) {
if (
body.channel_id !== process.env.DISCORD_CHANNEL_ID_KOR &&
body.channel_id !== process.env.DISCORD_CHANNEL_ID_EN
) {
console.log(`channel id ${body.channel_id}`);
console.log(
"This command is only available in the COMMUNITY category"
);
res.status(200).send({
type: 4,
data: {
content: `This command is only available in the 'COMMUNITY' category. 😒`,
},
});
return;
}
const discordBot = new DiscordBot();
const result = await discordBot.execute(body);
console.log(`result ${JSON.stringify(result)}`);
res.status(200).send(result);
console.log("reply done");
}
return;
} catch (e) {
console.error(e.message);
return res.send("Error handling verification");
}
}
);
deploy server on aws lambda
OAuth2 -> URL Generator, check bot, applications.commands and enter url then select server.
check SERVER MEMBERS INTENT, MESSAGE CONTENT INTENT
enter api gateway url to INTERACTIONS ENDPOINT URL as https://xyz.amazonaws.com/interactions/
create slash commands
const { Client, Intents } = require("discord.js");
const client = new Client({
intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES],
});
console.log(`NODE_ENV ${process.env.NODE_ENV}`);
require("dotenv").config({ path: `./.env.${process.env.NODE_ENV}` });
const korCommandList = {
γ……γ…‡γ„Ή: {
description: "예치 수읡λ₯  응닡",
},
수읡λ₯ : {
description: "예치 수읡λ₯  응닡",
},
예치수읡λ₯ : {
description: "예치 수읡λ₯  응닡",
},
};
const enCommandList = {
depositapy: {
description: "response deposit yield",
},
yield: {
description: "response deposit yield",
},
apy: {
description: "response deposit yield",
},
deposityield: {
description: "response deposit yield",
},
};
client.on("ready", async () => {
const promises = [];
const objs = Object.assign(korCommandList, enCommandList);
console.log(
`process.env.DISCORD_BOT_CLIENT_ID ${process.env.DISCORD_BOT_CLIENT_ID}`
);
console.log(`process.env.DISCORD_GUILD_ID ${process.env.DISCORD_GUILD_ID}`);
for (const key in objs) {
const p = await client.api
.applications(process.env.DISCORD_BOT_CLIENT_ID)
// .guilds(process.env.DISCORD_GUILD_ID)
.commands.post({
data: {
name: key,
description: objs[key].description,
},
});
promises.push(p);
}
const result = await Promise.all(promises);
console.log(result);
client.destroy();
});
client.login(process.env.DISCORD_BOT_TOKEN);
after hours, or day type / on discord app. normal user can not see commad list, but admin can see.
Expected Behavior
Every user on server with bot can see slash command list.
Current Behavior
Admin can see slash command lists, but normal user can not see.
Screenshots/Videos
text box by server admin
text box by server normal user, slash commands not displayed
Client and System Information
browser admin : chrome on mac
user : discord app on mac
lib

socket-io: when a message is sent, how to display a message/notification to the root component / out of the chatroom?

In my chat app when a message is emitted on a chatroom I want to display a message/toaster to the root component so that the person who is out of the chatroom will get notified.
useEffect(() => {
const token = localStorage.getItem('CC_Token');
if (token) {
const payload = JSON.parse(atob(token.split('.')[1]));
setUserId(payload.id);
}
if (socket) {
socket.on('newMessage', (message) => {
const newMessages = [...messages, message];
setMessages(newMessages);
});
}
//eslint-disable-next-line
}, [messages, socket]);
what I have tried is to dispatch an action and tried to update the redux store.
but the problem is reducer is not called.
What would be the best approach to achieve this
You use this code
const notifyMe = () => {
if (!('Notification' in window)) {
alert(
'This browser does not support desktop notification please use Chrome, Brave, Firefox or update your browser'
);
} else if (
Notification.permission === 'granted' ||
Notification.permission === 'default'
) {
var options = {
body: 'This is body of notification',
icon: 'notif.jpg',
dir: 'ltr',
};
var notification = new Notification('Hi there', options);
} else if (Notification.permission === 'denied') {
Notification.requestPermission((permission) => {
if (!('permission' in Notification)) {
Notification.permission = permission;
}
if (permission === 'granted') {
var options = {
body: 'This is body of notification',
icon: 'notif.jpg',
dir: 'ltr',
};
var notification = new Notification('Hi there', options);
}
});
}
};

Microsoft Graph API outlook send attachments

How do you send attachments with the Microsoft graph outlook API? I understand everything for sending attachments up until the content bytes. The files that I need to send are a word document a pdf and a jpeg Is it asking me to turn the file into bytes, if so how would I do that? I am using node.js and I have the following code:
exports.send_mail = async function(req, res, next) {
let parms = { title: 'Inbox', active: { inbox: true } };
const accessToken = await authHelper.getAccessToken(req.cookies, res);
const userName = req.cookies.graph_user_name;
if (accessToken && userName) {
parms.user = userName;
// Initialize Graph client
const client = graph.Client.init({
authProvider: (done) => {
done(null, accessToken);
}
});
//read test.html
//so you have to wait for the file to read then send it
message = fs.readFileSync('views/test.html', 'utf8');
console.log(rawImage.data.toString('utf8'))
try {
mailMess ={
message:{
subject: 'This is a test',
body:{
ContentType: 'HTML',
Content: message
},
ToRecipients:[
{
EmailAddress:{
Address: 'name#email.com'
}
}
],
"attachments": [
{
"#odata.type": "#microsoft.graph.fileAttachment",
"name": "attachment.jpeg",
"contentBytes": "not sure what to put here"
}
]
}
}
//sendmail
const result = await client
.api('/me/sendmail')
.version('v1.0')
.post(mailMess);
res.status('202')
parms.messages = result.value;
res.redirect('/');
} catch (err) {
parms.message = 'Error retrieving messages';
parms.error = { status: `${err.code}: ${err.message}` };
parms.debug = JSON.stringify(err.body, null, 2);
res.render('error', parms);
}
} else {
// Redirect to home
res.redirect('/');
}
}
I found out that param takes the file encoded as base64

Serverless notifications with Cloud Functions for Firebase

I have used firebase chat notification cloud function but when
notification triggered I am getting this error in firebase function
console
Cannot read property 'current' of undefined
at exports.sendNotification.functions.database.ref.onWrite.event (/user_code/index.js:8:35)
Here is my function:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/notifications/messages/{pushId}').onWrite(event => {
console.log('Push notification event triggered for testing');
console.log(event);
const message = event.data.current.val();
const senderUid = message.from;
const receiverUid = message.to;
console.log(receiverUid);
const promises = [];
if (senderUid === receiverUid) {
//if sender is receiver, don't send notification
promises.push(event.data.current.ref.remove());
return Promise.all(promises);
}
const getInstanceIdPromise = admin.database().ref(`/usersnew/${receiverUid}`).once('value');
const getSenderUidPromise = admin.auth().getUser(senderUid);
return Promise.all([getInstanceIdPromise, getSenderUidPromise]).then(results => {
const instanceId = results[0].val();
const sender = results[1];
console.log('notifying ' + receiverUid + ' about ' + message.body + ' from ' + senderUid);
const payload = {
notification: {
title: sender.displayName,
body: message.body,
icon: sender.photoURL
}
};
admin.messaging().sendToDevice(instanceId, payload)
.then(function (response) {
return console.log("Successfully sent message:", response);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
return console.log('This is the notify feature');
});
});
Does anyone know how to solve this?
When I log event it shows like below in console
{ before:
DataSnapshot {
app:
FirebaseApp {
firebaseInternals_: [Object],
services_: {},
isDeleted_: false,
name_: '__admin__',
options_: [Object],
INTERNAL: [Object] },
instance: 'https://teleport-24f52.firebaseio.com',
_path: '/notifications/messages/-LIlFNd2spo_V1rM-G-f',
_data: null },
after:
DataSnapshot {
app:
FirebaseApp {
firebaseInternals_: [Object],
services_: {},
isDeleted_: false,
name_: '__admin__',
options_: [Object],
INTERNAL: [Object] },
instance: 'https://teleport-24f52.firebaseio.com',
_path: '/notifications/messages/-LIlFNd2spo_V1rM-G-f',
_data:
{ body: 'abc',
dayTimestamp: 1532975400000,
from: 'q8gtwtwXqbV2DtpsrbYajFsWzSr2',
negatedTimestamp: -1533056068309,
timestamp: 1533056068309,
to: 'Cmpu7mbIENTYyoHZjCjZnbnBMbl2' } } }
10:22:44.625 PM
In your code, event.data.current should be event.after.val() , event.after.ref, etc...
There was a change of API in cloud functions 1.0.
Read:
https://firebase.google.com/docs/functions/database-events#reading_the_previous_value
https://firebase.google.com/docs/functions/beta-v1-diff
Maybe the problem is in the SDK version. From v1.0 things change a bit. Try updating SDK and follow these instructions for miragation:
https://firebase.google.com/docs/functions/beta-v1-diff

Push notification returns ECONNRESET in Google Cloud Functions

I am having a function in Firebase Cloud Functions that is retrieves the user's device group id in order to send a push notification, and after sends a push notification. This works well if the function gets called only once, but if I have an array of users I want to send a push notification too, the sendPushNotification function returns error : FAILED err= { RequestError: Error: read ECONNRESET
at new RequestError (/user_code/node_modules/request-promise/node_modules/request-promise-core/lib/errors.js:14:15) for every try to send push
From what i understand ECONNRESET means that the connection gets closed at one end before finishing the operation, can some help/explain me why this is:
here is my code:
function sendFollowNotification(snapshot) {
const notificationMsg = getFollowNotificationMsg() //returns a string
snapshot.forEach(function(singleUser, index) {
const userId = singleUser.key;
const userObject = singleUser.val();
console.log("will get device group")
if (index + 1 == snapshot.numChildren()) {
return getDeviceGroupNotificationKey(userId, "Discover new artists", notificationMsg, "", true);
} else {
getDeviceGroupNotificationKey(userId, "Discover new artists", notificationMsg, "", false);
}
}
function getDeviceGroupNotificationKey(groupId, notificationTitle, notificationBody, notificationSubject, shouldReturn) {
const pathToDeviceGroup = admin.database().ref('deviceGroups').child(groupId);
pathToDeviceGroup.once("value").then( function(snapshot) {
const deviceGroupObj = snapshot.val();
const notification_key = deviceGroupObj.notification_key;
console.log("got notification key")
console.log(notification_key)
if (notification_key !== undefined) {
return sendPushToDeviceGroupOld(notification_key, notificationTitle, notificationBody, "notificationKeyOld2", notificationSubject, shouldReturn);
} else {
return
}
}).catch(reason => {
console.log("user device group not there")
return
})
}
function sendPushToDeviceGroupOld(notification_key, title, body, subject, message, shouldReturn) {
console.log('sending push to ' + notification_key)
const serverKey = '-';
const senderId = '-';
const options = {
method: 'POST',
uri: 'https://fcm.googleapis.com/fcm/send',
headers: {
'Authorization': 'key=' + serverKey,
'project_id': senderId
},
body: {
to: notification_key,
data: {
subject: message
},
notification: {
title: title,
body: body,
badge: 1,
sound: "default",
},
priority : 'high',
content_available: true
},
json: true
};
return rqstProm(options)
.then((parsedBody) => {
console.log('SUCCESS response=', parsedBody);
return
})
.catch((err) => {
console.log('FAILED', err);
return
});
}

Resources