-1

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);

1 Answers1

0

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.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • CORS thing is not helping. I guess if it is CORS, It would not make calls from Web also. Not able to catch the calls from Fiddler etc known. – Goutam Kumar Dec 20 '22 at 10:39
  • This is not the indicator, CORS may prevent it working from the desktop application while the web is not affected. – Eugene Astafiev Dec 20 '22 at 16:09