I'm working on on tool that gives desktop notifications when page content has specific change. When I launch extension I have error in console that says " Cannot read properties of null (reading 'innerHTML') at snowAlerts (contentScript.js:26:69)".
When I paste same code in chrome snippets code works fine. Also what is worth to mention is that when I paste document.getElementById("3e731e79875e4d5089360d830cbb3517").innerHTML
in console I receive same error, but when I click on the selector and copy this "3e731e79875e4d5089360d830cbb3517" from elements and replace it in document.getElementById("3e731e79875e4d5089360d830cbb3517").innerHTML I receive correct output. I have no idea what may cause this problem, here is code for notification:
function snowAlerts() {
if (document.getElementById("3e731e79875e4d5089360d830cbb3517").innerHTML != '0') {
console.log("Do something");
function showNotification() {
if (Notification.permission !== 'granted') {
Notification.requestPermission();
} else {
const options = {
body: 'New Alert on SNOW',
dir: 'ltr',
};
const notification = new Notification('SNOW INCIDENT', options);
notification.onclick = function () {
window.open('MY SITE');
};
}
}
showNotification();
}
else {
console.log("Do nothing")
}
}
setInterval(snowAlerts, 5000);
Related
I'm trying to use the navigation.share API, in Firefox if i try to share a tweet for example, this open de twitter page and all is ok. But if i try the same in chrome the behavior is different, the share open a default prompt. There are a way to have the same behavior in each browser?
const shareUrl = (e, socialNetwork) => {
e.preventDefault();
e.stopPropagation();
if (navigator.share) {
navigator
.share({
title: document.title,
url: path,
})
.catch(console.error);
} else {
if (socialNetwork == "Facebook") {
shareFacebook(path);
}
if (socialNetwork == "Twitter") {
shareTwitter(path);
}
}
};
I am trying to create a Audio/Video Calling app using React Native. There's a screen in the app where calling happens using WebRTC. Let's call it 'Call' screen. TO show calling notification I am using the package react-native-callkeep. Once a user picks up the call, I'm taking him directly to the 'Call' screen. Everything works fine except when I'm trying to take the user to the 'Call' screen.
Here's how I'm doing it:
Inside my AppDelegate.m I have this
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application
continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void(^)(NSArray * __nullable restorableObjects))restorationHandler
{
return [RNCallKeep application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
Inside the index.js, I'm calling initCalling before registering the app like this:
...
initCalling();
AppRegistry.registerComponent(appName, () => App);
And Here's what initCalling does
const initCalling = () => {
const options = {
ios: {
appName: 'MyApp',
includesCallsInRecents: false,
imageName: 'notification_icon',
supportsVideo: true,
},
android: {
alertTitle: 'Permissions required',
alertDescription: 'This application needs to access your Calling Service',
cancelButton: 'Cancel',
okButton: 'ok',
imageName: 'notification_icon',
}
};
RNCallKeep.setup(options);
function checkCallNotification(message) {
if (!message.data.callType) {
return;
}
const { threadId, messageKey } = message.data;
RNCallKeep.displayIncomingCall(
message.data.channelId,
message.data.title,
message.data.title,
'number',
message.data.callType === 'video',
);
RNCallKeep.addEventListener('answerCall', async () => {
RNCallKeep.removeEventListener('endCall');
RNCallKeep.endAllCalls();
Linking.openURL(message.data.deeplink);
RNCallKeep.removeEventListener('answerCall');
});
RNCallKeep.addEventListener('endCall', () => {
RNCallKeep.endAllCalls();
RNCallKeep.removeEventListener('endCall');
});
}
messaging().setBackgroundMessageHandler(async (remoteMessage) => {
checkCallNotification(remoteMessage);
});
messaging().onMessage(async (remoteMessage) => {
checkCallNotification(remoteMessage);
});
}
When a notification arrives, the call keep starts showing the call screen. Once user picks up the call, Im trying to take him to the 'Call' screen but instead I'm getting this
index.bundle?platfor…&minify=false:41712 Possible Unhandled Promise Rejection (id: 0):
Error: Unable to open URL: myapp://call
Error: Unable to open URL: myapp://call
on debugging I can see the line Linking.openURL(message.data.deeplink); is failing even though the url is correct. And this is happening only in iOS. On Android things are working perfect. Can someone please help me know what I'm doing wrong ? Thanks !
I figured out how to make my Discord bot send an image to a certain channel whenever a specific user plays a specific game, but I have another problem.
When the application closes, I get this error saying, "Cannot read property 'name' of null." How do I fix this?
I haven't tried anything because I don't know anything about how I should use null.
// Game Detector \\
client.on("presenceUpdate", (oldMember, newMember) => {
if(newMember.id === '406742915352756235') {
if(newMember.presence.game.name === 'ROBLOX') { // New Example: ROBLOX
console.log('ROBLOX detected!');
client.channels.get('573671522116304901').send('**Joining Game:**', {
files: [
"https://cdn.discordapp.com/attachments/567519197052272692/579177282283896842/rblx1.png"
]
});
}
}
});
I expected the code to work, even when the application closes. Instead, it cannot read name of null. How can I fix this error?
This error is most likely thrown when the user stops playing a game, because newMember.presence.game will logically be null. Then, when you try to read name of newMember.presence.game, you receive your error.
Use this revised code:
client.on('presenceUpdate', (oldMember, newMember) => {
if (newMember.id !== '406742915352756235') return; // only check for this user
if (newMember.presence.game && newMember.presence.game.name === 'ROBLOX') {
console.log('ROBLOX detected.');
const channel = client.channels.get('573671522116304901');
if (!channel) return console.log('Unable to find channel.');
channel.send('**Joining Game:**', {
files: ['https://cdn.discordapp.com/attachments/567519197052272692/579177282283896842/rblx1.png']
}).catch(console.error);
}
});
My chrome extension keeps throwing an error to this function
function messageReceived(message) {
// A message is an object with a data property that
// consists of key-value pairs.
// Pop up a notification to show the GCM message.
chrome.notifications.create(getNotificationId(), {
title: message.data.name,
iconUrl: 'assets/img/cat.jpg',
type: 'basic',
message: message.data.prompt,
buttons : [
{ title: "Accept" },
{ title: "Reject" }
]
}, function() {});
}
Error:
Unchecked runtime.lastError while running notifications.create: Some of the required properties are missing: type, iconUrl, title and message.
at messageReceived
However, all these are actually present. The error arrives EVERYTIME I add the following function
function notificationBtnClicked(notification, ibtn) {
console.log(notification)
console.log(ibtn)
if (ibtn==0) {
chrome.storage.local.get("name", function(name){
chrome.storage.local.get("email",function(email){
//call other users
var email = email
var name = name
$.ajax({
url: 'some api',
data:'{email:email, name:name}',
ajax:true,
success: function(result)
{
alert(result);
}
});
});
})
}else {
//snooze
}
}
But, I don't understand what's the issue. I checked the chrome.storage by downloading some chrome extension that lets you view it and its there.
Why is the error incorrect? :/
chrome.gcm.onMessage.addListener(messageReceived);
chrome.notifications.onButtonClicked.addListener(notificationBtnClicked);
Make sure that all required notification properties have their value. The 'iconUrl' you used must be a data URL, a blob URL or URL related to a resource within the extension's .crx file required for 'notification.create' method. Please be mindful of the Chrome version you are using.
Also, include a callback and check chrome.runtime.lastError
function callback() {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError.message);
} else {
// Tab exists
}
}
I would liked to detect whether or not microphone permissions have been granted on my site when it loads without actually running something like the following:
navigator.webkitGetUserMedia({audio: active},
function(){alert('worked')},
function(){alert('failed')});
Is there a simple API to detect whether the user has permanently granted microphone access to my application (which runs over https)?
Update
microphone has been added to the Permission API even if it's not yet available on Safari nor Internet Explorer.
You could hope that it would be accessible from the permission api, but it isn't :(
Perhaps in the feature this could work like the rest of this:
navigator.permissions.query(
// { name: 'camera' }
{ name: 'microphone' }
// { name: 'geolocation' }
// { name: 'notifications' }
// { name: 'midi', sysex: false }
// { name: 'midi', sysex: true }
// { name: 'push', userVisibleOnly: true }
// { name: 'push' } // without userVisibleOnly isn't supported in chrome M45, yet
).then(function(permissionStatus){
console.log(permissionStatus.state); // granted, denied, prompt
permissionStatus.onchange = function(){
console.log("Permission changed to " + this.state);
}
})
Old answer
The only way i see it possible is if you keep track of this yourself with a key/value item in localStorage when you ask for permission.
Unfortunately it doesn't notify you when it has been changed
// initialization
if( localStorage.getItem('voice_access') === null ){
// just assume it is prompt
localStorage.setItem('voice_access', 'prompt');
}
// Then somewhere
navigator.getUserMedia({ audio: true }, function (e) {
// http://stackoverflow.com/q/15993581/1008999
//
// In chrome, If your app is running from SSL (https://),
// this permission will be persistent.
// That is, users won't have to grant/deny access every time.
localStorage.setItem("voice_access", "granted");
}, function (err) {
if (err.name === 'PermissionDismissedError') {
localStorage.setItem('voice_access', 'prompt')
}
if (err.name === 'PermissionDeniedError') {
localStorage.setItem('voice_access', 'denied')
}
})
You could go the extra mile and build a nice little wrapper with this code above and extend/replace the permission api to handle more enum names and create a broadcast api to tell the other tabs when it changes. but why make it so complicated...? The localStorage can't be 100% trusted. it can be changed anywhere any time both with permission and storage cleared
you already got the polling method for checking permissions.
here is some information from MDN:
https://developer.mozilla.org/en-US/docs/Web/API/Navigator.getUserMedia
and some more: https://developer.mozilla.org/en-US/docs/WebRTC
here is an example:
navigator.getMedia (
// constraints
{
video: true,
audio: true
},
// successCallback
function(localMediaStream) {
var video = document.querySelector('video');
video.src = window.URL.createObjectURL(localMediaStream);
video.onloadedmetadata = function(e) {
// Do something with the video here.
};
},
// errorCallback
function(err) {
console.log("The following error occured: " + err);
}
);
navigator.getUserMedia is now obsolete, replaced by MediaDevices.getUserMedia, which returns a promise. If the promise gets rejected you get an DOMException with indication of the problem. Insufficient permissions is one of the options there.
Details here:
https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia
I guess this would be helpful:
function isMicrophoneAllowed(){
navigator.permissions.query({
name: 'microphone'
}).then(function(permissionStatus){
return permissionStatus.state !== 'denied';
});
}