Unable to call any API from onAppointmentSend? Is this a limtation? Codes working on web outlook but not for Desktop Outlook - outlook

these are similar issues posted online
Relative fetch or XHR in a UI-Less Outlook add-in on Windows
How to make a http request in Outlook add-ins?
Officejs - Addin Outlook - SmartAlerts
Add-in built on jQuery framework works well on web-based outlook but doesn't on Desktop App
Outlook OnNewMessageCompose event not firing in Windows client
In outlook add-ins make salesforce oauth2 auth request getting CORS error
Common JavaScript function for Outlook Add-ins
React fetch not working with localhost endpoint with spring boot backend but ok with dummy JSON data
What is the easiest way to integrate Outlook web add-in into an existing ASP.NET Core 6 application?
Outlook Addin getting CORS when making request to ewsURL
if (_contextInfo.platform == "PC") {
console.log("PC");
Office.context.mailbox.item.subject.setAsync("Set by: New", { "asyncContext": event },
function (asyncResultPC) {
if (asyncResultPC.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultPC.error));
}
asyncResult.asyncContext.completed();
});
$.when(GetToken()).done(function () {
Office.context.mailbox.item.subject.setAsync("GetToken" + objResourceCurrent.token, { "asyncContext": event },
function (asyncResultToken) {
if (asyncResultToken.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultToken.error));
}
asyncResult.asyncContext.completed();
});
/*if (isNotNull(originalAppointment)) {
SetResourceAvailabilityByDatetimeRequest(originalAppointment);
if (objResourceCurrent.token != "" && objResourceCurrent.availabilityCriteria.length > 0) {
GetResourceAvailabilityByDatetime();
}
}*/
});
event.completed({ allowEvent: false, errorMessage: "From Desktop" });
}
else if (_contextInfo.platform == "OfficeOnline") {
console.log("OfficeOnline");
Office.context.mailbox.item.start.getAsync((asyncResultStartDt) => {
if (asyncResultStartDt.status !== Office.AsyncResultStatus.Succeeded) {
console.error(`Start Error:: ${asyncResultStartDt.error.message}`);
event.completed();
return;
}
originalAppointment.start = convertDateCS(asyncResultStartDt.value);
Office.context.mailbox.item.end.getAsync(function (asyncResultEndDt) {
if (asyncResultEndDt.status !== Office.AsyncResultStatus.Succeeded) {
console.error(`End Error:: ${asyncResultEndDt.error.message}`);
event.completed();
return;
}
originalAppointment.end = convertDateCS(asyncResultEndDt.value);
Office.context.mailbox.item.sessionData.getAsync("bookingObject", function (asyncResultBO) {
if (asyncResultBO.status !== Office.AsyncResultStatus.Succeeded) {
console.error(`BO Error:: ${asyncResultBO.error.message}`);
event.completed();
return;
}
const bookingObjectAllData = JSON.parse(asyncResultBO.value);
$.each(bookingObjectAllData["Office365AddInBookingItem"], function (index, item) { if (item.IsAddon == false) { ResourceIds = ResourceIds + item.ResourceId + ","; } });
originalAppointment.ResourceIds = ResourceIds;
result = checkRoomAvailabilityOutlook(originalAppointment.ResourceIds, originalAppointment.start, originalAppointment.end);
if (result) {
$.each(result, function (id, item) {
if (item.Value) {
availableRooms.push(item.Key)
}
else {
unAvailableRooms.push(item.Key)
}
});
}
else {
event.completed({ allowEvent: false, errorMessage: "checkRoomAvailabilityOutlook API Responsed with No Data" });
}
if (unAvailableRooms.length > 0) {
$.each(bookingObjectAllData["Office365AddInBookingItem"], function (index, item) {
if ($.inArray(item.ResourceId, unAvailableRooms) !== -1)
unavailableEmails = unavailableEmails !== '' ? unavailableEmails + ', ' + item.ResourceEmailId : item.ResourceEmailId;
});
event.completed({ allowEvent: false, errorMessage: "Unavailable room(s): " + unavailableEmails });
}
else {
if (availableRooms.length > 0) {
$.each(bookingObjectAllData["Office365AddInBookingItem"], function (index, item) {
if ($.inArray(item.ResourceId, availableRooms) !== -1)
availableEmails = availableEmails !== '' ? availableEmails + ', ' + item.ResourceEmailId : item.ResourceEmailId;
});
}
}
var itemId = Office.context.mailbox.item.itemId;
if (itemId === null || itemId == undefined) {
Office.context.mailbox.item.saveAsync(function (asyncResultSave) {
if (asyncResultSave.status !== Office.AsyncResultStatus.Succeeded) {
console.error(`End Error:: ${asyncResultSave.error.message}`);
event.completed();
return;
}
bookingObjectAllData.ExchangeReferenceNumber = asyncResultSave.value;
createSaveBookingRequest(bookingObjectAllData, originalAppointment);
saveBooking(bookingObj);
console.log(JSON.stringify(bookingObjectAllData));
event.completed({ allowEvent: true, errorMessage: "ItemId: " + asyncResultSave.value });
});
}
else {
console.log("Item already saved");
}
});
});
});
}
I tried XMLHttpRequest and fetch. both fails.
function GetToken() {
return $.ajax({
cache: false,
type: "POST",
contentType: "application/json",
url: "https://xyz/xyz/token",
data: {
username: "abc...",
password: "r6COP...",
grant_type: "password",
},
success: function (result) {
objResourceCurrent.token = result.access_token;
},
error: function (error) {
console.log("GetToken Error ", error);
}
});
}
Update
My above issue is still not resolved however As a test, I am able to call this open weather API. It working just fine with Windows Desktop/Web Outlook's OnSend or timeChange event handlers.
function onAppointmentSendHandler(event) {
console.log("onAppointmentSendHandler");
const _contextInfo = Office.context.diagnostics;
if (_contextInfo.platform == "PC") {
var url = 'https://api.openweathermap.org/data/2.5/weather?lat=28.644800&lon=77.216721&appid=efc8b889e4d57fbcc6fb2b523d2558c8';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.send();
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
console.log(request.responseText);
const myObj = JSON.parse(request.responseText)
var _Dtext = "From Desktop: City: " + myObj.name + ", Temp: " + myObj.main.temp + "f";
Office.context.mailbox.item.subject.setAsync(_Dtext, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
event.completed({ allowEvent: false });
});
}
else {
console.log("Problem retrieving data PC");
console.log(this.responseXML);
}
}
}
}
else if (_contextInfo.platform == "OfficeOnline") {
console.log("Office Online");
var url = 'https://api.openweathermap.org/data/2.5/weather?lat=28.474388&lon=77.503990&appid=efc8b889e4d57fbcc6fb2b523d2558c8';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.send();
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
//console.log(request.responseText);
const myObj = JSON.parse(request.responseText)
var _Otext = "From Online: City: " + myObj.name + ", Temp: " + myObj.main.temp + "f";
Office.context.mailbox.item.subject.setAsync(_Otext, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
event.completed({ allowEvent: false });
});
}
else {
console.log("Problem retrieving data Office Online");
console.log(this.responseXML);
}
}
}
}
}
function onAppointmentTimeChangedHandler(event) {
console.log("onAppointmentTimeChangedHandler");
var url = 'https://api.openweathermap.org/data/2.5/weather?lat=23.669296&lon=86.151115&appid=efc8b889e4d57fbcc6fb2b523d2558c8';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.send();
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
console.log(request.responseText);
const myObj = JSON.parse(request.responseText)
var _text = "From Time Change: City: " + myObj.name + ", Temp: " + myObj.main.temp + "f";
Office.context.mailbox.item.subject.setAsync(_text, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
});
}
else {
console.log("Problem retrieving data");
console.log(this.responseXML);
}
}
}
}
Office.actions.associate("onAppointmentTimeChangedHandler", onAppointmentTimeChangedHandler);
Office.actions.associate("onAppointmentSendHandler", onAppointmentSendHandler);
Update 2 I am testing another API with 3 fields Subject, StartDate and End Date. Please note: This below code runs perfectly on Web outlook for OnSend/TimeChange events but not for Desktop Outlook OnSend /TimeChange events. And I do not get any error message or something.
Any help is much appriciated.
function onAppointmentSendHandler(event) {
console.log("onAppointmentSendHandler");
const _contextInfo = Office.context.diagnostics;
if (_contextInfo.platform == "PC") {
var obj = JSON.stringify({
Subject: "Azure Desktop 1",
StartDate: "03/02/2023",
EndDate: "03/31/2023"
});
username = "admin1";
password = "pass#123";
var url = 'https://externalwebapi.azurewebsites.net/api/save';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
request.send(obj);
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
console.log(request.responseText);
var _Dtext = "Azure Desktop 1";
Office.context.mailbox.item.subject.setAsync(_Dtext, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject1: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
event.completed({ allowEvent: false });
});
}
else {
console.log("Problem retrieving data PC");
console.log(this.responseXML);
}
}
}
}
else if (_contextInfo.platform == "OfficeOnline") {
console.log("Office Online");
var obj = JSON.stringify({
Subject: "Azure WebSite 1",
StartDate: "02/02/2023",
EndDate: "02/28/2023"
});
//console.log(obj);
username = "admin1";
password = "pass#123";
var url = 'https://externalwebapi.azurewebsites.net/api/save';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
request.send(obj);
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
console.log(request.responseText);
var _Dtext = "Azure WebSite 1";
Office.context.mailbox.item.subject.setAsync(_Dtext, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
event.completed({ allowEvent: false });
});
}
else {
console.log("Problem retrieving data Web");
console.log(this.responseXML);
}
}
}
}
}
function onAppointmentTimeChangedHandler(event) {
console.log("onAppointmentTimeChangedHandler");
var obj = JSON.stringify({
Subject: "Azure Time",
StartDate: "02/02/2023",
EndDate: "02/28/2023"
});
username = "admin1";
password = "pass#123";
var url = 'https://externalwebapi.azurewebsites.net/api/save';
var request = new XMLHttpRequest();
request.onreadystatechange = state_change;
request.open("POST", url, true);
request.setRequestHeader("Authorization", "Basic " + btoa(username + ":" + password));
request.setRequestHeader('Content-type', 'application/json; charset=utf-8');
request.send(obj);
function state_change() {
if (request.readyState == "4") {
if (request.status == "200") {
console.log(request.responseText);
var _Dtext = "Azure Time";
Office.context.mailbox.item.subject.setAsync(_Dtext, { "asyncContext": event }, function (asyncResultWeb) {
if (asyncResultWeb.status !== Office.AsyncResultStatus.Succeeded) {
console.error("Failed to set subject2: " + JSON.stringify(asyncResultWeb.error));
}
asyncResultWeb.asyncContext.completed();
event.completed({ allowEvent: false });
});
}
else {
console.log("Problem retrieving data Web");
console.log(this.responseXML);
}
}
}
}
Office.actions.associate("onAppointmentTimeChangedHandler", onAppointmentTimeChangedHandler);
Office.actions.associate("onAppointmentSendHandler", onAppointmentSendHandler);

REST API calls are supported and can be made from the onSend event handlers (callbacks). You just need to make sure that CORS is addressed in the add-in. The very first link in your post contains the valid answer to your case.
The same-origin policy enforced by the browser prevents a script loaded from one domain from getting or manipulating properties of a webpage from another domain. This means that, by default, the domain of a requested URL must be the same as the domain of the current webpage. For example, this policy will prevent a webpage in one domain from making XmlHttpRequest web-service calls to a domain other than the one where it is hosted.
Because Office Add-ins are hosted in a browser control, the same-origin policy applies to script running in their web pages as well.
The same-origin policy can be an unnecessary handicap in many situations, such as when a web application hosts content and APIs across multiple subdomains. There are a few common techniques for securely overcoming same-origin policy enforcement. The Addressing same-origin policy limitations in Office Add-ins article can only provide the briefest introduction to some of them.

Related

How to play DRM content using native WebOS player

We are trying to play video content using native WebOS player and com.webos.service.drm service. The goal is to play at least some DRM content (dash+widevine or hls+widevine). Clear content works fine, but DRM content stucks completely, and no diagnostic messages appear.
The same result happens on WebOS 3.4, 4.4, and 6.0. Is there any working example of DRM content playback?
Our code is given below.
var appId = "com.zodiac.app";
// Define DRM Type
var drmType = "widevine";
function webos_request(service, params)
{
var caller = arguments.callee.caller.name;
console.log("REQ: %s: %s %s", caller, service, JSON.stringify(params))
return new Promise( function(resolve, reject) {
webOS.service.request(service, Object.assign({}, params, {
onSuccess: function (result) { console.log("REQ SUCCESS: %s: %s %s: %s", caller, service, params.method, JSON.stringify(result)); resolve(result) },
// onFailure: function (result) {
// console.log("[" + result.errorCode + "] " + result.errorText);
// reject()
// }
onFailure: function (result) { console.error("REQ ERROR: %s: %s %s: %s", caller, service, params.method, JSON.stringify(result)); reject(result) }
}))
});
}
function webos_subscribe(service, params, method)
{
var caller = arguments.callee.caller.name;
var completed = false
return new Promise( function(resolve, reject) {
params.parameters = params.parameters || {}
params.parameters.subscribe = true;
console.log("SUB: %s: %s %s", caller, service, JSON.stringify(params))
webOS.service.request("luna://com.webos.service.drm", Object.assign({}, params, {
onSuccess: function (result) { // Subscription Callback
if (!completed) {
completed = true;
if (result.subscribed) {
console.log("SUB: %s: %s: SUCCESS", caller, service)
resolve(result)
}
else {
console.error("SUB: %s: %s: FAILED", caller, service)
reject();
}
}
else
method(result)
},
onFailure: function (result) {
console.error("SUB: %s: %s: onFailure", caller, service, result)
// console.log('Player.subscribeLicensingError onFailure: ' + '[' + result.errorCode + '] ' + result.errorText);
completed = true;
reject()
}
}));
});
}
function unloadDrmClient(clientId)
{
webos_request("luna://com.webos.service.drm",
{
method:"unload",
parameters: {
"clientId": result.clientId
}
});
}
function loadDrmClient()
{
return webos_request( "luna://com.webos.service.drm", {
method:"load",
parameters: {
"drmType": drmType,
"appId": appId
}})
.then(function (result) {
console.log("DRM Client is loaded successfully. %s", JSON.stringify(result));
document.addEventListener('visibilitychange', function() {
if (document.visibilityState === 'hidden') {
unloadDrmClient(result.clientId)
}
})
return result.clientId
})
}
function sendRightInformation(clientId, url, la_url) {
var msgId;
// Message format for widevine
var msg = [
'<?xml version="1.0" encoding="utf-8"?>',
'<WidevineCredentialsInfo xmlns="http://www.smarttv-alliance.org/DRM/widevine/2012/protocols/">',
'<ContentURL>' + url + '</ContentURL>',
'<DeviceID></DeviceID>',
'<StreamID></StreamID>',
'<ClientIP></ClientIP>',
'<DRMServerURL>' + la_url + '</DRMServerURL>',
'<DRMAckServerURL></DRMAckServerURL>',
'<DRMHeartBeatURL></DRMHeartBeatURL>',
'<DRMHeartBeatPeriod>0</DRMHeartBeatPeriod>',
'<UserData></UserData>',
'<Portal></Portal>',
'<StoreFront></StoreFront>',
'<BandwidthCheckURL></BandwidthCheckURL>',
'<BandwidthCheckInterval></BandwidthCheckInterval>',
'</WidevineCredentialsInfo>',
].join("")
// Message type for widevine
var msgType = "application/widevine+xml";
// Unique ID of DRM system
var drmSystemId = "urn:dvb:casystemid:19156";
return webos_request( "luna://com.webos.service.drm", {
method:"sendDrmMessage",
parameters: {
"clientId": clientId,
"msgType": msgType,
"msg": msg,
"drmSystemId": drmSystemId
}})
.then( function (result) {
// DRM API does not return the msgId, resultCode, resultMsg for Widevine type.
console.log("sendDrmMessage succeeded. %s", JSON.stringify(result));
return
});
}
function subscribeLicensingError(clientId, msgId)
{
return webos_subscribe("luna://com.webos.service.drm", {
method:"getRightsError",
parameters: {
"clientId": clientId
}},
function (result) { // Subscription Callback
var contentId = result.contentId;
if (contentId == msgId) {
if ( 0 == result.errorState) {
console.log("No license");
// Do something for error handling
}
else if ( 1 == result.errorState) {
console.log("Invalid license");
// Do something for error handling
}
else {
console.log("Unknown errorState: %s", JSON.stringify(result));
}
}
else {
console.log("skip notification %s", JSON.stringify(result));
}
});
}
var video = document.getElementById('myVideo');
function playback()
{
var config = {
'dash+wv': {
type: "application/dash+xml",
mediaTransportType: "WIDEVINE",
url: 'https://bitmovin-a.akamaihd.net/content/art-of-motion_drm/mpds/11331.mpd',
la_url: 'https://widevine-proxy.appspot.com/proxy'
},
'hls+wv': {
type: "application/x-mpegURL",
mediaTransportType: "HLS",
url: 'https://storage.googleapis.com/shaka-demo-assets/angel-one-widevine-hls/hls.m3u8',
la_url: 'https://cwip-shaka-proxy.appspot.com/no_auth'
},
'mp4': {
type: "video/mp4",
url: "https://jsoncompare.org/LearningContainer/SampleFiles/Video/MP4/Sample-MP4-Video-File-Download.mp4"
},
'hls': {
type: "application/vnd.apple.mpegurl",
url: "https://bitdash-a.akamaihd.net/content/MI201109210084_1/m3u8s/f08e80da-bf1d-4e3d-8899-f0f6155f6efa.m3u8",
},
'dash': {
type: "application/dash+xml",
url: 'https://storage.googleapis.com/shaka-demo-assets/bbb-dark-truths/dash.mpd'
}
}
var stream = config['hls+wv']
var prepare
if (stream.la_url) {
prepare = loadDrmClient()
.then( function(id) {
subscribeLicensingError(id, undefined);
document.body.addEventListener("unload", function() {
webOS.service.request("luna://com.webos.service.drm", {
method:"unload",
parameters: { "clientId": id },
onSuccess: function (result) {
console.log("DRM Client is unloaded successfully.");
},
onFailure: function (result) {
console.log("[" + result.errorCode + "] " + result.errorText);
// Do something for error handling
}
});
})
return sendRightInformation(id, stream.url, stream.la_url).then( function () { return id; })
})
}
else {
prepare = Promise.resolve()
}
return prepare.then( function (id) {
var type = stream.type
if (stream.la_url) {
var options = {
mediaTransportType: stream.mediaTransportType,
option: {
drm: {
type: drmType,
clientId: id,
}
}
};
console.log("Options: %s", JSON.stringify(options));
var mediaOption = encodeURIComponent(JSON.stringify(options));
type += ';mediaOption=' + mediaOption;
}
console.log("open url: %s", stream.url)
console.log("type : %s", type)
var source = document.createElement("source");
source.setAttribute('src', stream.url);
source.setAttribute('type', type);
video.addEventListener('loadedmetadata', function(event) {
console.log("loadedmetadata %O", event)
});
video.addEventListener('error', function(e) {
console.error('error', e);
});
video.addEventListener('stalled', function(e) {
console.log('stalled', e);
});
video.addEventListener('loadeddata', function() {
console.log('[Device_Webos_Player] loadeddata');
});
video.addEventListener('loadedmetadata', function() {
console.log('[Device_Webos_Player] loadedmetadata');
});
video.addEventListener('canplay', function () {
console.log('[Device_Webos_Player] canplay');
});
video.addEventListener('durationchange', function() {
console.log('[Device_Webos_Player] durationchange: ' + video.duration);
});
video.addEventListener('timeupdate', function() {
console.log('[Device_Webos_Player] timeupdate: ' + video.currentTime);
}, { once: true});
video.appendChild(source);
// video.load()
video.play()
})
}
playback()
Finally the idea is [see here]
MPEG-DASH streaming is officially not supported on the webOS TV.
HLS plays AES-128 DRM only in public version
HTML5 EME/MSE can use both widevine and playready
See "Streaming Protocol & DRM Combination" here

Service Worker "notificationclick" not firing

The notification is showing fine, but when I click on it, or any of the actions, nothing happens. I see no logging, no error messages, but the notification does close (although it closes even when I comment out the event.notification.close()).
I've tried using the Chrome debugger, and I can set a break point in the code that shows the notification, but all breakpoints within the notificationclick handler fail to pause execution.
I've spent days trying to get this to work and I'm at my wits' end.
const auth = firebase.auth();
const functions = firebase.functions();
const done = functions.httpsCallable("done");
const snooze = functions.httpsCallable("snooze");
self.addEventListener("notificationclick", event => {
console.log("notificationclick", event);
const uid = auth.currentUser.uid;
const { id, url } = event.notification.data;
event.notification.close();
event.waitUntil(() => {
switch (event.action) {
case "done":
console.log("Done");
return done({ uid, id });
case "snooze1":
console.log("Snooze 1 Hour");
return snooze({ uid, id, hours: 1 });
case "snooze24":
console.log("Snooze 1 Day");
return snooze({ uid, id, hours: 24 });
default:
console.log("Open App");
return clients
.matchAll({
includeUncontrolled: true,
type: "window"
})
.then(clientList => {
for (let i = 0; i < clientList.length; i++) {
let client = clientList[i];
if (url[0] === "#") {
if (client.url.endsWith(url) && "focus" in client) {
return client.focus();
}
} else {
if (
client.url.replace(/#.*$/, "") === url &&
"focus" in client
) {
return client.focus();
}
}
}
if (clients.openWindow) {
return clients.openWindow(location.origin + url);
}
});
}
});
});
firebase
.messaging()
.setBackgroundMessageHandler(({ data: { title, options } }) => {
options = JSON.parse(options);
options.actions = [
{ action: "done", title: "Done" },
{ action: "snooze1", title: "Snooze 1 Hour" },
{ action: "snooze24", title: "Snooze 1 Day" }
];
return self.registration.showNotification(title, options);
});
Hi Could you try below code and see if this is getting called-
self.addEventListener('notificationclick', function (event) {
event.notification.close();
var redirectUrl = null;
var tag = event.notification.tag;
if (event.action) {
redirectUrl = event.action
}
if (redirectUrl) {
event.waitUntil(async function () {
var allClients = await clients.matchAll({
includeUncontrolled: !0
});
var chatClient;
for (const client of allClients) {
if (redirectUrl != '/' && client.url.indexOf(redirectUrl) >= 0) {
client.focus();
chatClient = client;
break
}
}
if (chatClient == null || chatClient == 'undefined') {
chatClient = clients.openWindow(redirectUrl);
return chatClient
}
}().then(result => {
if (tag) {
//PostAction(tag, "click")
}
}))
}
});
Edited-
Attaching both js files. it is working at my end.
firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');
var config = {
apiKey: "your api key",
authDomain: "you firebase domain",
databaseURL: "your firbase db url",
projectId: "your project id",
storageBucket: "",
messagingSenderId: "sender id"
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function (payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload.data);
var notificationTitle = payload.data.Title;
var notificationOptions = {
body: payload.data.Body,
icon: payload.data.Icon,
image: payload.data.Image,
action: payload.data.ClickAction
};
console.log("strated sending msg" + notificationOptions);
return self.registration.showNotification(notificationTitle,notificationOptions);
});
self.addEventListener('notificationclick', function (event) {
console.log('On notification click: ', event.notification);
event.notification.close();
var redirectUrl = null;
if (event.notification.data) {
if (event.notification.data.FCM_MSG) {
redirectUrl = event.notification.data.FCM_MSG.data ? event.notification.data.FCM_MSG.data.click_action : null
} else {
redirectUrl = event.notification.data ? event.notification.data.click_action : null
}
}
console.log("redirect url is : " + redirectUrl);
if (redirectUrl) {
event.waitUntil(async function () {
var allClients = await clients.matchAll({
includeUncontrolled: true
});
var chatClient;
for (var i = 0; i < allClients.length; i++) {
var client = allClients[i];
if (client['url'].indexOf(redirectUrl) >= 0) {
client.focus();
chatClient = client;
break;
}
}
if (chatClient == null || chatClient == 'undefined') {
chatClient = clients.openWindow(redirectUrl);
return chatClient;
}
}());
}
});
self.addEventListener("notificationclose", function (event) {
event.notification.close();
console.log('user has clicked notification close');
});
application.js file :
/// <reference path="scripts/jquery-3.3.1.js" />
try {
var config = {
apiKey: "your api key",
authDomain: "you firebase domain",
databaseURL: "your firbase db url",
projectId: "your project id",
storageBucket: "",
messagingSenderId: "sender id"
};
firebase.initializeApp(config);
if ('serviceWorker' in navigator && 'PushManager' in window) {
console.log('Service Worker and Push is supported');
navigator.serviceWorker
.register('/firebase-messaging-sw.js')
.then((swReg) => {
firebase.messaging().useServiceWorker(swReg);
askForPermissioToReceiveNotifications();
})
.catch(function (error) {
console.error('Service Worker Error', error);
window.alert("Service Worker Error" + error);
})
} else {
console.warn('Push messaging is not supported');
window.alert("Push messaging is not supported " + (navigator.serviceWorker));
}
const askForPermissioToReceiveNotifications = async () => {
try {
const messaging = firebase.messaging();
console.log(messaging);
await messaging.requestPermission();
const token = await messaging.getToken();
if (token !== null || token !== 'undefined') {
await sendDeviceTokenToServerSide(token);
}
console.log('Got token : ' + token);
messaging.onMessage(function (payload) {
console.log('onMessage: ', payload);
setTimeout(() => {
navigator.serviceWorker.ready.then(function (registration) {
var notificationTitle = payload.notification.title;
var notificationOptions = {
body: payload.notification.body,
data: payload.data,
icon: payload.notification.icon,
image: payload.data.Image,
requireInteraction: payload.notification.requireInteraction,
tag: payload.notification.tag,
click_action: payload.data.click_action,
requireInteraction: true
};
registration.showNotification(notificationTitle, notificationOptions);
},50)
});
});
}
catch (e) { console.log('error in getting token: ' + e); window.alert("error in getting token: " + e); }
}
function sendDeviceTokenToServerSide(token) {
$.ajax({
type: 'POST',
url: '/Home/StoreToken',
timeout: 5000000,
data: { token: token },
success: function (success) {
console.log("device token is sent to server");
},
error: function (error) {
console.log("device error sending token to server : " + error);
window.alert("device error sending token to server : " + error);
}
});
}
} catch (e) {
window.alert("error: " + e);
}
function GetFcmUserToken(messaging) {
messaging.onTokenRefresh(function () {
messaging.getToken()
.then(function (refreshedToken) {
console.log('Token refreshed.');
return refreshedToken;
})
.catch(function (err) {
console.log('Unable to retrieve refreshed token ', err);
showToken('Unable to retrieve refreshed token ', err);
});
});
}
self.addEventListener('notificationclick', function (event) {
const clickedNotification = event.notification;
// Do something as the result of the notification click
const promiseChain = clients.openWindow(clickedNotification.data.Url);
event.waitUntil(promiseChain);
});
This code inside service worker js worked fine for me on chrome Desktop and Android.

ExpressJS Ajax request is getting redirected/Aborted

I'm trying to make an AJAX request to one of my routes which should return some data, but I can't solve the fact that when I make an AJAX request I'm being redirected to the route I'm requesting.
How can I prevent this from happening?
Ajax:
var request = new XMLHttpRequest();
var url = 'http://localhost:3000/signin';
var credentials = {
email: document.getElementsByName('email')[0].value,
password: document.getElementsByName('password')[0].value
};
JSON.stringify(credentials);
request.onreadystatechange = function() {
if (request.readyState == XMLHttpRequest.DONE) {
if(request.status == 200) {
if(request.readyState == 4) {
var data = JSON.parse(request.responseText);
console.log(data);
}
} else if(request.status == 400) {
console.log('There was an error 400');
} else {
console.log('something else other than 200 was returned');
}
}
}
request.open('POST', url, true);
request.setRequestHeader('Accept', 'application/json');
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader("X-Requested-With", "XMLHttpRequest");
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
request.send(credentials);
Api Endpoint:
app.post('/signin', function(req, res) {
request.post({
url:'http://localhost:3000/api/authenticate',
form: {
email: req.body.email,
hashed_password: req.body.password
},
}, function(err, httpResponse, body) {
console.log(req.xhr);
console.log(req.headers);
if (err) {
return console.error('failed:', err);
}
console.log('successful! ', JSON.parse(body));
//user.token = data.token;
res.json(JSON.parse(body));
});
});

AJAX POST request on IE fails with error "No Transport"?

I'm trying to make an AJAX request to a public service
Here's the code:
$.ajax({
url : "http://api.geonames.org/citiesJSON",
type : 'POST',
cache : false,
dataType : 'json',
data : {
username: "demo",
north:10,
south: 10,
east:10,
west:10}
}).done(function(data) {
alert("Success: " + JSON.stringify(data));
}).fail(function(a, b, c, d) {
alert("Failure: "
+ JSON.stringify(a) + " "
+ JSON.stringify(b) + " "
+ JSON.stringify(c) + " "
+ JSON.stringify(d) );
});
You may try it in this link: http://jsfiddle.net/hDXq3/
The response is retrieved successfully on Chrome & Firefox, and the output is as follows:
But for IE, the fails alerting:
Failure: {"readyState":0,"status":0,"statusText":"No Transport"} "error" "No Transport" undefined
Why it's not working on IE ? and how to fix this ?
Here's the solution for those who are interested:
if (!jQuery.support.cors && window.XDomainRequest) {
var httpRegEx = /^https?:\/\//i;
var getOrPostRegEx = /^get|post$/i;
var sameSchemeRegEx = new RegExp('^'+location.protocol, 'i');
var xmlRegEx = /\/xml/i;
// ajaxTransport exists in jQuery 1.5+
jQuery.ajaxTransport('text html xml json', function(options, userOptions, jqXHR){
// XDomainRequests must be: asynchronous, GET or POST methods, HTTP or HTTPS protocol, and same scheme as calling page
if (options.crossDomain && options.async && getOrPostRegEx.test(options.type) && httpRegEx.test(userOptions.url) && sameSchemeRegEx.test(userOptions.url)) {
var xdr = null;
var userType = (userOptions.dataType||'').toLowerCase();
return {
send: function(headers, complete){
xdr = new XDomainRequest();
if (/^\d+$/.test(userOptions.timeout)) {
xdr.timeout = userOptions.timeout;
}
xdr.ontimeout = function(){
complete(500, 'timeout');
};
xdr.onload = function(){
var allResponseHeaders = 'Content-Length: ' + xdr.responseText.length + '\r\nContent-Type: ' + xdr.contentType;
var status = {
code: 200,
message: 'success'
};
var responses = {
text: xdr.responseText
};
try {
if (userType === 'json') {
try {
responses.json = JSON.parse(xdr.responseText);
} catch(e) {
status.code = 500;
status.message = 'parseerror';
//throw 'Invalid JSON: ' + xdr.responseText;
}
} else if ((userType === 'xml') || ((userType !== 'text') && xmlRegEx.test(xdr.contentType))) {
var doc = new ActiveXObject('Microsoft.XMLDOM');
doc.async = false;
try {
doc.loadXML(xdr.responseText);
} catch(e) {
doc = undefined;
}
if (!doc || !doc.documentElement || doc.getElementsByTagName('parsererror').length) {
status.code = 500;
status.message = 'parseerror';
throw 'Invalid XML: ' + xdr.responseText;
}
responses.xml = doc;
}
} catch(parseMessage) {
throw parseMessage;
} finally {
complete(status.code, status.message, responses, allResponseHeaders);
}
};
xdr.onerror = function(){
complete(500, 'error', {
text: xdr.responseText
});
};
xdr.open(options.type, options.url);
//xdr.send(userOptions.data);
xdr.send();
},
abort: function(){
if (xdr) {
xdr.abort();
}
}
};
}
});
};
jQuery.support.cors = true;
$.ajax({
url : "http://api.geonames.org/citiesJSON",
crossDomain: true,
type : 'POST',
cache : false,
dataType : 'json',
data : {
username: "demo",
north:10,
south: 10,
east:10,
west:10}
}).done(function(data) {
alert("Success: " + JSON.stringify(data));
}).fail(function(a, b, c, d) {
alert("Failure: "
+ JSON.stringify(a) + " "
+ JSON.stringify(b) + " "
+ JSON.stringify(c) + " "
+ JSON.stringify(d) );
});
You may try it in this link: http://jsfiddle.net/bjW8t/4/
Just include the jQuery ajaxTransport extension that uses XDomainRequest for IE8+.

Backbone collection fetch error with no information

I have a strange problem with the fetch of a backbone collection I am working with. In one particular instance of my code I perform a fetch (exactly how I do it in other areas of the code which all work fine), the fetch never seems to make it to the server and the developer tools shows the request as red with the word (canceled) in the status/text field.
I've walked this through into the backbone sync method and I see the $.ajax being built and everything looks fine. Has anyone run into this problem?
here is my code if it helps, this is a function that calls two .ashx services to first check for a file's existence then to open it. The part that isn't working for me is the "me.collection.fetch().
openDocument: function () {
var me = this,
fileId = me.model.get('id'),
userId = Dashboard.Data.Models.UserModel.get("UserInfo").User_ID,
fileRequest = '/genericHandlers/DownloadFile.ashx?id=' + fileId + '&userId=' + userId,
fileCheck = '/genericHandlers/CheckFileExistance.ashx?id=' + fileId + '&userId=' + userId;
//hide tooltip
me.hideButtonTooltips();
// Check for file existance
$.ajax({
url: fileCheck
})
.done(function (data) {
if (data && data === "true") {
document.location.href = fileRequest;
me.collection.fetch();
} else if (!!data && data === "false") {
"This file is no longer available.".notify('error');
}
})
.fail(function (data) {
"Something went wrong during the File Existance check".notify('error');
"Something went wrong during the File Existance check".log(userId, 'error', 'Docs');
});
},
my collection:
// docsCollection.js - The collection of ALL the documents available to a given user
// Document Collection
Dashboard.Collections.DocsCollection = Backbone.Collection.extend({
model: Dashboard.Models.DocumentUploadModel,
url: function () {
return 'apps/docs/Docs/' + this.userId;
},
initialize: function (options) {
this.userId = options.userId;
this.deferredFetch = this.fetch();
},
comparator: function (model) {
return -(new Date(model.get('expirationDate')));
},
getDaysSinceViewedDocuments: function () {
return this.filter(function (model) {
return model.get('daysSinceViewed') !== null;
});
},
getNewDocuments: function () {
return this.filter(function (model) {
return model.get('isNew');
});
},
getExpiredDocuments: function () {
return this.filter(function (model) {
return model.get('isExpired');
});
}
});
and my model:
Dashboard.Models.DocumentUploadModel = Backbone.Model.extend({
defaults: {
fileArray: [],
name: '',
description: '',
accesses: [],
tags: [],
expirationDate: ''
},
initialize: function () {
this.set({
userId: Dashboard.Data.Models.UserModel.get("UserInfo").User_ID,
expirationDate: (this.isNew()) ? buildExpirationDate() : this.get('expirationDate')
}, { silent: true });
function buildExpirationDate() {
var date = new Date((new Date()).getTime() + 24 * 60 * 60 * 1000 * 7),
dateString = "{0}/{1}/{2}".format(date.getMonth() + 1, date.getDate(), date.getFullYear());
return dateString;
}
},
firstFile: function () {
return this.get('fileArray')[0];
},
validate: function (attributes) {
var errors = [];
if (attributes.name === '' || attributes.name.length === 0)
errors.push({
input: 'input.txtName',
message: "You must enter a name."
});
if (attributes.description === '' || attributes.description.length === 0)
errors.push({
input: 'textarea.taDescription',
message: "You must enter a description."
});
if (errors.length > 0)
return errors;
return;
},
sync: function (method, model, options) {
var formData = new FormData(),
files = model.get("fileArray"),
$progress = $('progress'),
success = options.success,
error = options.error;
// Nothing other than create or update right now
if (method !== "create" && method !== "update")
return;
// Build formData object
formData.append("name", model.get("name"));
formData.append("description", model.get("description"));
formData.append("accesses", model.get("accesses"));
formData.append("tags", model.get("tags"));
formData.append("expirationDate", model.get("expirationDate"));
formData.append("userId", model.get("userId"));
formData.append("isNew", model.isNew());
// if not new then capture id
if (!model.isNew())
formData.append('id', model.id);
for (var i = 0; i < files.length; i++) {
formData.append('file', files[i]);
}
xhr = new XMLHttpRequest();
xhr.open('POST', '/genericHandlers/UploadDocsFile.ashx');
xhr.onload = function () {
if (xhr.status === 200) {
if (success)
success();
} else {
if (error)
error();
}
}
if ($progress.length > 0) {
xhr.upload.onprogress = function (evt) {
var complete;
if (evt.lengthComputable) {
// Do the division but if you cant put 0
complete = (evt.loaded / evt.total * 100 | 0);
$progress[0].value = $progress[0].innerHTML = complete;
}
}
}
xhr.send(formData);
},
upload: function (changedAttrs, options) {
this.save("create", changedAttrs, options);
}
});
You're assigning a value to document.location.href before you try to fetch your collection:
document.location.href = fileRequest;
me.collection.fetch();
Changing document.location.href will change the whole page and in the process, any currently running JavaScript will get shutdown so I wouldn't expect your me.collection.fetch() to ever get executed.

Resources