Aus der Praxis: Outlook Mail App und der leere Body
avatar

Bei der Entwicklung von Microsoft Office Mail Apps bin ich nun schon zwei Mal über ein Phänomen gestolpert, sodass ich mich nun entschlossen habe dieses für andere schriftlich festzuhalten.

Greift man in einer Office Mail App im Bereich „Read Form“ auf die Eigenschaft „Body“ einer Nachricht zu, dann hat diese den Wert undefined! Und dabei ist doch der Inhalt der Nachricht das Wichtigste!

 

Wie kam es mal wieder dazu

In der Softwareentwicklung arbeiten professionelle Firmen mit Bugtracking-Systemen, um während der Umsetzungs- und Testphase Fehler an zentraler Stelle zu verwalten. In meinen Projekten kommt fast ausschließlich der Team Foundation Server (TFS) zum Einsatz.

Eigentlich können die Tester auftretende Fehler direkt im TFS erfassen; oft fehlt es ihnen aber an Knowhow oder Motivation die TFS-Funktionalitäten zu nutzen. Somit kommen Fehlermeldung und Changes oft per Email rein und müssen dann von Hand in den TFS übertragen werden.

clip_image002

 

Die App

Um den oben genannten manuellen Aufwand zu sparen, habe ich vor kurzem (eher als Spielerei/ PoC) eine Office Mail App entwickelt, die diesen Vorgang abkürzen soll. Emails können direkt als Task oder Bug an den TFS gesendet werden.

Wenn man im Outlook Client, im OWA oder in Office 365 für eine Email im Postfach eine App realisieren möchte, dann benötigt man eine Implementierung für den Bereich „Read Form“.

clip_image004

 

Über die JavaScript API können die Eigenschaften der Nachricht einwandfrei ausgelesen werden. Greift man allerdings auf den Inhalt zu, dann muss man leider feststellen, dass die Eigenschaft „Office.context.mailbox.item.body“ den Wert ‚undefined‘ hat.

 

clip_image006

Dies ist im ersten Augenblick auf jeden Fall etwas verwunderlich, da doch der Inhalt der Nachricht eigentlich genau das Interessanteste ist. Auch in meinem Fall wollte ich den Inhalt an den TFS übergeben und griff prompt ins Leere.

Microsoft erklärt dieses Phänomen damit, dass der Inhalt einer Nachricht durchaus sehr groß sein kann und daher nicht pauschal geladen werden sollte. Aha! Und nun?

Microsoft empfiehlt diese Eigenschaft explizit nachzuladen. Und zwar über die EWS (Exchange Web Services) mit der Methode makeEwsRequestAsync. Dafür müsst ihr allerdings die Berechtigung der App auf „Read write mailbox“ hochstufen, falls dies nicht bereits der Fall ist.

image

 

Über diesen Weg könnt ihr übrigens auch alle übrigen Eigenschaften einer Nachricht oder eines Termins aus dem Exchange Server auslesen werden. Unter ‚ https://msdn.microsoft.com/en-us/library/office/dn600367(v=exchg.150).aspx ‘ könnt ihr nachschlagen, welche Eigenschaft generell verfügbar sind.

Nachfolgend ist mein Code abgebildet, um den Body einer Message zu laden. Wie gesagt, nur ein PoC! 😉

/// <reference path="../App.js" />

(function () {
    "use strict";

    // var url = "https://webaccess.tfs.hansevision.com/wi.aspx?pname=Spielwiese Max&wit=Bug&[Title]=Bug Bash&[Area Path]=Spielwiese Max\Spielwiese Max Reader";

    // The Office initialize function must be run each time a new page is loaded
    Office.initialize = function (reason) {
        $(document).ready(function () {
            app.initialize();
            registerClickHandler();

            var item = Office.context.mailbox.item;
            var mailbox = Office.context.mailbox;
            $('#workitemtitle-id').val(item.subject)
      

        });
    };

    function getItemRequest(id) {
        // Return a GetItem operation request for the subject of the specified item. 
        var result =
     '<?xml version="1.0" encoding="utf-8"?>' +
     '<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' +
     '               xmlns:xsd="http://www.w3.org/2001/XMLSchema"' +
     '               xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"' +
     '               xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">' +
     '  <soap:Header>' +
     '    <RequestServerVersion Version="Exchange2013" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" soap:mustUnderstand="0" />' +
     '  </soap:Header>' +
     '  <soap:Body>' +
     '    <GetItem xmlns="http://schemas.microsoft.com/exchange/services/2006/messages">' +
     '      <ItemShape>' +
     '        <t:BaseShape>IdOnly</t:BaseShape>' +
     '        <t:AdditionalProperties>' +
     '            <t:FieldURI FieldURI="item:Body"/>' +
     '        </t:AdditionalProperties>' +
     '      </ItemShape>' +
     '      <ItemIds><t:ItemId Id="' + id + '"/></ItemIds>' +
     '    </GetItem>' +
     '  </soap:Body>' +
     '</soap:Envelope>';
        return result;
    }

    function ewsCallback(asyncResult) {
        var result = asyncResult.value;
        if (asyncResult.status == "succeeded") {
            app.showNotification('EWS-Abfrage', "Erfolgreich!");

            var response = $.parseXML(asyncResult.value);

            var extendedProps1 = response.getElementsByTagName("t:Body");
            if (extendedProps1.length == 1) {

                var project = encodeURI($("#workitemProject-id option:selected").text());
                var title = encodeURI($('#workitemtitle-id').val());
                
                var content = extendedProps1[0].textContent;
                content = content.substring(content.indexOf('<body'), content.length - 1);
                content = content.substring(content.indexOf('>') + 1, content.length - 1);
                content = content.substring(0, content.indexOf('</body>'));

                var content = encodeURI(content);
                var url = 'https://webaccess.tfs.hansevision.com/tfs/Entwicklungsprojekte/' + project +
                         '/_workItems/create/Bug?%5BSystem.Title%5D=' + title + '&%5BMicrosoft.VSTS.TCM.ReproSteps%5D=' + content;

                window.open(url);
            }
        }
        else {
            app.showNotification('EWS-Abfrage', "Fehlergeschlagen!");
        }
    }

    function sendToTfs() {
        var item = Office.context.mailbox.item;
        var mailbox = Office.context.mailbox;
        mailbox.makeEwsRequestAsync(getItemRequest(mailbox.item.itemId), ewsCallback);
    }

    function registerClickHandler() {
       var item = Office.context.mailbox.item;
        if (item.itemType === Office.MailboxEnums.ItemType.Message) {
            $('#btn-sendTfs').click(function () {
                sendToTfs();
            });
        }
    }

})();

 

Nachdem der Button “OK” in der App geklickt wurde, öffnet sich die TFS-Seite, um einen wie in diesem Fall einen neuen Bug zu erfassen.

clip_image010

 

Ich möchte an dieser Stelle auch noch mal kurz auf ein weiteres potentielles Problem hinweisen. In meiner neuen Entwicklungsmaschine wurde die Mail App in meinem Outlook Client nicht angezeigt.

Nach kurzer Recherche habe ich das Problem gefunden. Wenn Ihr in eurer App Manifest den Eintrag <Set Name=“MailBox“ MinVersion=“1.1″ />‘ habt, dann müsst ihr Office 2013 SP1 installieren! 😉

Office 2013 SP1 builds haben die Nummer 15.0.4569 und höher.

 

Schlusswort

Ich hoffe dieser Betrag hat euch gefallen oder konnte euch sogar weiterhelfen!

Schreibe einen Kommentar