Schreiben einer Node.js-App zum Abrufen von Outlook-Mail, -Kalender und -Kontakten

In diesem Leitfaden werden Sie schrittweise durch den Prozess des Erstellens einer einfachen Node.js-App zum Abrufen von Nachrichten in Office 365 oder Outlook.com geführt. Wenn Sie die hier beschriebenen Schritte ausführen, sollte der Quellcode in diesem Repository das Ergebnis sein.

In diesem Leitfaden wird Microsoft Graph zum Zugriff auf Outlook-Mail verwendet. Microsoft empfiehlt die Verwendung von Microsoft Graph für den Zugriff auf Outlook-Mail, -Kalender und -Kontakte. Verwenden Sie die Outlook-APIs nur dann direkt (über https://outlook.office.com/api), wenn Sie ein Feature benötigen, das in den Graph-Endpunkten nicht verfügbar ist. Eine Version dieses Beispiels mit Verwendung der Outlook-APIs finden Sie in dieser Verzweigung.

In diesem Leitfaden wird davon ausgegangen, dass Sie Node.js bereits installiert haben und auf Ihrem Entwicklungscomputer ausführen.

Erstellen der App

Lassen Sie uns direkt loslegen. Erstellen Sie ein leeres Verzeichnis, in dem Sie die neue Node.js-App erstellen möchten. Für die Zwecke dieses Leitfadens wird davon ausgegangen, dass der Name des Verzeichnisses node-tutorial ist, Sie können aber gerne einen beliebigen Namen verwenden.

Öffnen Sie eine Eingabeaufforderung im Verzeichnis node-tutorial, und führen Sie den folgenden Befehl aus:

npm init

Drücken Sie bei allen Eingabeaufforderungen die EINGABETASTE, um die Standardeinstellungen zu übernehmen. Wenn Sie fertig sind, sollten Sie über eine package.json-Basisdatei verfügen. Öffnen Sie diese Datei mit Ihrem bevorzugten JavaScript-Editor, und ersetzen Sie den vorhandenen scripts-Wert durch Folgendes:

"scripts": {
  "start": "node index.js"
},

Erstellen Sie eine neue Datei namens server.js. Fügen Sie den folgenden Code in server.js ein, und speichern Sie die Datei.

Inhalt der Datei .\server.js

var http = require('http');
var url = require('url');

function start(route, handle) {
  function onRequest(request, response) {
    var pathName = url.parse(request.url).pathname;
    console.log('Request for ' + pathName + ' received.');
    route(handle, pathName, response, request);
  }

  var port = 8000;
  http.createServer(onRequest).listen(port);
  console.log('Server has started. Listening on port: ' + port + '...');
}

exports.start = start;

Wenn Sie mit Node.js vertraut sind, ist dies nichts Neues für Sie. Wenn Sie nicht damit vertraut sind: Dies ist der Basiscode, der die Ausführung von Node.js auf einem Webserver ermöglicht, der an Port 8000 lauscht. Wenn Anforderungen eingehen, sendet er diese an die route-Funktion, die wir implementieren müssen.

Erstellen Sie eine neue Datei namens router.js, und fügen Sie den folgenden Code hinzu.

Inhalt der Datei .\router.js

function route(handle, pathname, response, request) {
  console.log('About to route a request for ' + pathname);
  if (typeof handle[pathname] === 'function') {
    return handle[pathname](response, request);
  } else {
    console.log('No request handler found for ' + pathname);
    response.writeHead(404 ,{'Content-Type': 'text/plain'});
    response.write('404 Not Found');
    response.end();
  }
}

exports.route = route;

Der Code sucht basierend auf dem angeforderten Pfad nach einer aufzurufenden Funktion. Er verwendet das handle-Array, das wir noch nicht definiert haben. Erstellen Sie eine neue Datei namens index.js, und fügen Sie den folgenden Code hinzu.

Inhalt der Datei .\index.js

var server = require('./server');
var router = require('./router');

var handle = {};
handle['/'] = home;

server.start(router.route, handle);

function home(response, request) {
  console.log('Request handler \'home\' was called.');
  response.writeHead(200, {'Content-Type': 'text/html'});
  response.write('<p>Hello world!</p>');
  response.end();
}

An diesem Punkt sollten Sie über eine funktionierende App verfügen. Öffnen Sie eine Eingabeaufforderung in dem Verzeichnis, in dem Ihre Dateien gespeichert sind, und geben Sie den folgenden Befehl ein.

npm start

Sie sollten eine Bestätigung mit der Meldung Server has started. erhalten. Öffnen Sie Ihren Browser, und navigieren Sie zu http://localhost:8000. „Hello world!“ sollte angezeigt werden.

Da wir nun bestätigt haben, dass die App funktioniert, können wir uns an die echte Arbeit machen.

Entwerfen der App

Unsere App ist sehr einfach. Wenn ein Benutzer die Website besucht, sieht er einen Link zum Anmelden und Anzeigen seiner E-Mails. Beim Klicken auf den Link gelangt er zur Azure-Anmeldeseite, wo er sich mit seinem Office 365- oder Outlook.com-Konto anmelden und unserer App Zugriff gewähren kann. Schließlich wird er zurück zu unserer App geleitet, die eine Liste der neuesten E-Mails im Posteingang des Benutzers anzeigt.

Als Erstes ersetzen wir die Nachricht „Hello world!“ durch einen Link für die Anmeldung. Hierzu ändern wir die home-Funktion in index.js. Öffnen Sie diese Datei in Ihrem bevorzugten Text-Editor. Aktualisieren Sie die home-Funktion so, dass sie dem folgenden Code entspricht.

Aktualisierte home-Funktion

function home(response, request) {
  console.log('Request handler \'home\' was called.');
  response.writeHead(200, {'Content-Type': 'text/html'});
  response.write('<p>Please <a href='#'>sign in</a> with your Office 365 or Outlook.com account.</p>');
  response.end();
}

Wie Sie sehen, ist unsere Startseite sehr einfach. Im Moment führt der Link noch keine Aktion aus, das werden wir aber bald ändern.

Registrieren der App

Wichtig

Neue App-Registrierungen sollten im Anwendungsregistrierungsportal erstellt und verwaltet werden, damit sie mit Outlook.com kompatibel sind. Erstellen Sie neue App-Registrierungen nur dann im Azure-Verwaltungsportal Folgendes auf Ihre App zutrifft:

  • Sie verwendet den OAuth2 Client Credentials Grant-Fluss oder
  • Sie muss neben Outlook auf andere Office 365-Arbeitslasten zugreifen (z. B. OneDrive for Business oder SharePoint)

Beachten Sie, dass mithilfe des Azure-Verwaltungsportals registrierte Apps nicht mit Outlook.com kompatibel sind und dass Berechtigungsbereiche nicht dynamisch angefordert werden können. Vorhandene App-Registrierungen, die im Azure-Verwaltungsportal erstellt wurden, funktionieren weiterhin nur für Office 365. Diese Registrierungen werden nicht im Anwendungsregistrierungsportal angezeigt und müssen im Azure-Verwaltungsportal verwaltet werden.

Kontoanforderungen

Um das Anwendungsregistrierungsportal zu verwenden, benötigen Sie entweder ein Office 365-Geschäfts- oder Schulkonto oder ein Microsoft-Konto. Wenn Sie nicht über eines dieser Konten verfügen, haben Sie verschiedene Möglichkeiten:

  • Registrieren Sie sich hier für ein neues Microsoft-Konto.
  • Sie haben mehrere Möglichkeiten, ein Office 365-Abonnement zu erhalten:

REST-API-Verfügbarkeit

Die REST-API ist derzeit auf allen Office 365-Konten, die über Exchange Online verfügen, sowie auf allen Outlook.com-Konten aktiviert.

Wechseln Sie zum App-Registrierungsportal, um schnell eine App-ID und einen geheimen Schlüssel abzurufen.

  1. Melden Sie sich über den Link Anmelden mit Ihrem Microsoft-Konto (Outlook.com) oder Ihrem Geschäfts-, Schul- oder Unikonto (Office 365) an.
  2. Klicken Sie auf die Schaltfläche App hinzufügen. Geben Sie node-tutorial für den Namen ein, und klicken Sie auf Anwendung erstellen.
  3. Suchen Sie den Abschnitt Anwendungsgeheimnisse, und klicken Sie auf die Schaltfläche Neues Kennwort generieren. Kopieren Sie nun das Kennwort, und speichern Sie es an einem sicheren Ort. Nachdem Sie das Kennwort kopiert haben, klicken Sie auf Ok.
  4. Suchen Sie den Abschnitt Plattformen, und klicken Sie auf Plattform hinzufügen. Wählen Sie Web aus, und geben Sie dann http://localhost:8000/authorize unter Umleitungs-URIs ein.
  5. Klicken Sie auf Speichern, um die Registrierung abzuschließen. Kopieren Sie die App-ID, und speichern Sie sie zusammen mit dem Kennwort, das Sie zuvor kopiert haben. Wir benötigen diese Werte bald.

So sollten die Details Ihrer App-Registrierung aussehen, wenn Sie fertig sind.

Screenshot der abgeschlossenen App-Registrierung im App-Registrierungsportal

Implementieren von OAuth2

Unser Ziel in diesem Abschnitt ist es, den Link auf unserer Startseite so einzurichten, dass der OAuth2-Autorisierungscodegenehmigungs-Fluss mit Azure AD initiiert wird. Der Einfachheit halber verwenden wir die simple-oauth2-Bibliothek für das Verarbeiten unserer OAuth-Anforderungen. Geben Sie an der Eingabeaufforderung den folgenden Befehl ein.

npm install simple-oauth2 --save

Jetzt ist die Bibliothek installiert und kann verwendet werden. Erstellen Sie eine neue Datei namens authHelper.js. Wir beginnen, indem wir zunächst eine Funktion zum Generieren der Anmelde-URL definieren.

Inhalt der Datei .\authHelper.js

var credentials = {
  client: {
    id: 'YOUR APP ID HERE',
    secret: 'YOUR APP PASSWORD HERE',
  },
  auth: {
    tokenHost: 'https://login.microsoftonline.com',
    authorizePath: 'common/oauth2/v2.0/authorize',
    tokenPath: 'common/oauth2/v2.0/token'
  }
};
var oauth2 = require('simple-oauth2').create(credentials);

var redirectUri = 'http://localhost:8000/authorize';

// The scopes the app requires
var scopes = [ 'openid',
               'User.Read',
               'Mail.Read' ];

function getAuthUrl() {
  var returnVal = oauth2.authorizationCode.authorizeURL({
    redirect_uri: redirectUri,
    scope: scopes.join(' ')
  });
  console.log('Generated auth url: ' + returnVal);
  return returnVal;
}

exports.getAuthUrl = getAuthUrl;

Als Erstes definieren wir die Client-ID und den geheimen Clientschlüssel. Außerdem definieren wir eine Umleitungs-URI und ein Array von Bereichen. Das Bereichsarray enthält die Bereiche openid, User.Read und Mail.Read, da die E-Mails des Benutzers nur gelesen werden sollen. Ersetzen Sie YOUR APP ID HERE durch die Anwendungs-ID und YOUR APP PASSWORD HERE durch das Kennwort, das Sie in Schritt 3 generiert haben; speichern Sie anschließend die Änderungen.

Zurück zur Codierung

Nachdem wir nun über tatsächliche Werte für die Client-ID und den geheimen Clientschlüssel verfügen, bringen wir die simple-oauth-Bibliothek zum Einsatz. Ändern Sie die home-Funktion in der Datei index.js so, dass die getAuthUrl-Funktion verwendet wird, um den Link auszufüllen. Sie müssen die authHelper-Datei anfordern, um Zugriff auf diese Funktion zu erhalten.

Aktualisierter Inhalt der Datei .\index.js

var server = require('./server');
var router = require('./router');
var authHelper = require('./authHelper');

var handle = {};
handle['/'] = home;

server.start(router.route, handle);

function home(response, request) {
  console.log('Request handler \'home\' was called.');
  response.writeHead(200, {'Content-Type': 'text/html'});
  response.write('<p>Please <a href="' + authHelper.getAuthUrl() + '">sign in</a> with your Office 365 or Outlook.com account.</p>');
  response.end();
}

Speichern Sie Ihre Änderungen, und navigieren Sie zu http://localhost:8000. Wenn Sie den Mauszeiger über den Link bewegen, sollte dies folgendermaßen aussehen:

https://login.microsoftonline.com/common/oauth2/authorize?redirect_uri=http%3A%2F%2Flocalhost%3A8000%2Fauthorize&scope=openid+User.Read+Mail.Read&response_type=code&client_id=<SOME GUID>

Der Abschnitt <SOME GUID> sollte mit Ihrer Client-ID übereinstimmen. Klicken Sie auf den Link. Daraufhin sollte die Anmeldeseite angezeigt werden. Melden Sie sich mit Ihrem Office 365- oder Outlook.com-Konto an. Ihr Browser sollte nun zurück zu unserer App geleitet werden, und es sollte der folgende Fehler angezeigt werden:

404 Not Found

Grund für diesen Fehler ist, dass wir noch keine Route für das Verarbeiten des /authorize-Pfads implementiert haben, den wir als unseren Umleitungs-URI hartcodiert haben. Im Folgenden werden wir diesen Fehler beheben.

Austauschen des Codes durch ein Token

Zunächst fügen wir eine Route für den /authorize-Pfad zum handle-Array in index.js hinzu.

Aktualisiertes handle-Array in .\index.js####

var handle = {};
handle['/'] = home;
handle['/authorize'] = authorize;

Die hinzugefügte Zeile teilt dem Router mit, dass beim Eingang einer GET-Anforderung für /authorize die authorize-Funktion aufgerufen werden soll. Damit dies funktioniert, müssen wir also diese Funktion implementieren. Fügen Sie die folgende Funktion zu index.js hinzu.

authorize-Funktion in der Datei .\index.js

var url = require('url');
function authorize(response, request) {
  console.log('Request handler \'authorize\' was called.');

  // The authorization code is passed as a query parameter
  var url_parts = url.parse(request.url, true);
  var code = url_parts.query.code;
  console.log('Code: ' + code);
  response.writeHead(200, {'Content-Type': 'text/html'});
  response.write('<p>Received auth code: ' + code + '</p>');
  response.end();
}

Starten Sie den Node-Server neu, und aktualisieren Sie Ihren Browser (oder wiederholen Sie den Anmeldevorgang). Anstelle eines Fehlers sollte nun der Wert des Autorisierungscodes auf dem Bildschirm angezeigt werden. Das ist zwar schon besser, aber immer noch nicht sehr hilfreich. Lassen Sie uns nun tatsächlich etwas mit dem Code ausführen.

Wir fügen eine weitere Hilfsfunktion mit dem Namen getTokenFromCode zu authHelper.js hinzu.

getTokenFromCode in der Datei .\authHelper.js

function getTokenFromCode(auth_code, callback, response) {
  var token;
  oauth2.authorizationCode.getToken({
    code: auth_code,
    redirect_uri: redirectUri,
    scope: scopes.join(' ')
  }, function (error, result) {
    if (error) {
      console.log('Access token error: ', error.message);
      callback(response, error, null);
    } else {
      token = oauth2.accessToken.create(result);
      console.log('Token created: ', token.token);
      callback(response, null, token);
    }
  });
}

exports.getTokenFromCode = getTokenFromCode;

Abrufen der E-Mail-Adresse des Benutzers

Wir verwenden das Zugriffstoken das erste Mal, um die E-Mail-Adresse des Benutzers aus der Outlook-API abzurufen. Sie werden bald sehen, warum wir das tun.

Um die Outlook-API zu verwenden, installieren Sie die Microsoft Graph-JavaScript-Clientbibliothek über die Befehlszeile.

npm install @microsoft/microsoft-graph-client es6-promise --save

Fordern Sie dann die microsoft-graph-client-Bibliothek an, indem Sie die folgende Zeile zu index.js hinzufügen.

var microsoftGraph = require("@microsoft/microsoft-graph-client");

Fügen Sie eine neue getUserEmail-Funktion zu index.js hinzu.

getUserEmail in der Datei .\index.js

function getUserEmail(token, callback) {
  // Create a Graph client
  var client = microsoftGraph.Client.init({
    authProvider: (done) => {
      // Just return the token
      done(null, token);
    }
  });

  // Get the Graph /Me endpoint to get user email address
  client
    .api('/me')
    .get((err, res) => {
      if (err) {
        callback(err, null);
      } else {
        callback(null, res.mail);
      }
    });
}

Nun möchten wir sicherstellen, dass diese funktioniert. Ändern Sie die authorize-Funktion in der Datei index.js so, dass diese Hilfsfunktionen verwendet und die Rückgabewerte angezeigt werden. Beachten Sie, dass die getToken-Funktion asynchron ist, daher müssen wir eine Rückruffunktion implementieren, um die Ergebnisse zu erhalten.

Aktualisierte authorize-Funktion in .\index.js

function authorize(response, request) {
  console.log('Request handler \'authorize\' was called.');

  // The authorization code is passed as a query parameter
  var url_parts = url.parse(request.url, true);
  var code = url_parts.query.code;
  console.log('Code: ' + code);
  authHelper.getTokenFromCode(code, tokenReceived, response);
}

tokenReceived-Rückruffunktion in .\index.js

function tokenReceived(response, error, token) {
  if (error) {
    console.log('Access token error: ', error.message);
    response.writeHead(200, {'Content-Type': 'text/html'});
    response.write('<p>ERROR: ' + error + '</p>');
    response.end();
  } else {
    getUserEmail(token.token.access_token, function(error, email) {
      if (error) {
        console.log('getUserEmail returned an error: ' + error);
        response.write('<p>ERROR: ' + error + '</p>');
        response.end();
      } else if (email) {
        response.writeHead(200, {'Content-Type': 'text/html'});
        response.write('<p>Email: ' + email + '</p>');
        response.write('<p>Access token: ' + token.token.access_token + '</p>');
        response.end();
      }
    });
  }
}

Wenn Sie Ihre Änderungen speichern, den Server neu starten und den Anmeldevorgang erneut durchlaufen, sollten die E-Mail-Adresse des Benutzers und eine lange Zeichenfolge von scheinbar unsinnigen Zeichen angezeigt werden. Wenn alles nach Plan läuft, sollte dies ein Zugriffstoken sein.

Im Folgenden ändern wir unseren Code so, dass das Token und die E-Mail-Adresse nicht angezeigt, sondern in einem Sitzungscookie gespeichert werden.

Neue Version der tokenReceived-Funktion

function tokenReceived(response, error, token) {
  if (error) {
    console.log('Access token error: ', error.message);
    response.writeHead(200, {'Content-Type': 'text/html'});
    response.write('<p>ERROR: ' + error + '</p>');
    response.end();
  } else {
    getUserEmail(token.token.access_token, function(error, email){
      if (error) {
        console.log('getUserEmail returned an error: ' + error);
        response.write('<p>ERROR: ' + error + '</p>');
        response.end();
      } else if (email) {
        var cookies = ['node-tutorial-token=' + token.token.access_token + ';Max-Age=3600',
                       'node-tutorial-email=' + email + ';Max-Age=3600'];
        response.setHeader('Set-Cookie', cookies);
        response.writeHead(302, {'Location': 'http://localhost:8000/mail'});
        response.end();
      }
    }); 
  }
}

Außerdem fügen wir eine Hilfsfunktion zum Lesen der Cookiewerte hinzu.

getValueFromCookie in .\index.js

function getValueFromCookie(valueName, cookie) {
  if (cookie.indexOf(valueName) !== -1) {
    var start = cookie.indexOf(valueName) + valueName.length + 1;
    var end = cookie.indexOf(';', start);
    end = end === -1 ? cookie.length : end;
    return cookie.substring(start, end);
  }
}

Aktualisieren des Zugriffstokens

Von Azure zurückgegebene Zugriffstoken sind eine Stunde lang gültig. Wenn Sie das Token verwenden, nachdem es abgelaufen ist, geben die API-Aufrufe 401-Fehler zurück. Sie könnten den Benutzer bitten, sich erneut anzumelden, aber die bessere Option besteht darin, das Token automatisch zu aktualisieren.

Zu diesem Zweck muss die App den offline_access-Bereich anfordern. Fügen Sie diesen Bereich dem scopes-Array in authHelper.js hinzu:

// The scopes the app requires
var scopes = [ 'openid',
               'offline_access',
               'User.Read',
               'Mail.Read' ];

Dies bewirkt, dass die Tokenantwort von Azure ein Aktualisierungstoken enthält. Wir werden nun die tokenReceived-Funktion so aktualisieren, dass das Aktualisierungstoken und die Ablaufzeit in einem Sitzungscookie gespeichert werden.

Neue Version der tokenReceived-Funktion

function tokenReceived(response, error, token) {
  if (error) {
    console.log('Access token error: ', error.message);
    response.writeHead(200, {'Content-Type': 'text/html'});
    response.write('<p>ERROR: ' + error + '</p>');
    response.end();
  } else {
    getUserEmail(token.token.access_token, function(error, email){
      if (error) {
        console.log('getUserEmail returned an error: ' + error);
        response.write('<p>ERROR: ' + error + '</p>');
        response.end();
      } else if (email) {
        var cookies = ['node-tutorial-token=' + token.token.access_token + ';Max-Age=4000',
                       'node-tutorial-refresh-token=' + token.token.refresh_token + ';Max-Age=4000',
                       'node-tutorial-token-expires=' + token.token.expires_at.getTime() + ';Max-Age=4000',
                       'node-tutorial-email=' + email + ';Max-Age=4000'];
        response.setHeader('Set-Cookie', cookies);
        response.writeHead(302, {'Location': 'http://localhost:8000/mail'});
        response.end();
      }
    }); 
  }
}

Fügen Sie nun eine Hilfsfunktion in index.js hinzu, um das zwischengespeicherte Token abzurufen, zu überprüfen, ob es abgelaufen ist, und es ggf. zu aktualisieren.

getAccessToken in der Datei .\index.js

function getAccessToken(request, response, callback) {
  var expiration = new Date(parseFloat(getValueFromCookie('node-tutorial-token-expires', request.headers.cookie)));

  if (expiration <= new Date()) {
    // refresh token
    console.log('TOKEN EXPIRED, REFRESHING');
    var refresh_token = getValueFromCookie('node-tutorial-refresh-token', request.headers.cookie);
    authHelper.refreshAccessToken(refresh_token, function(error, newToken){
      if (error) {
        callback(error, null);
      } else if (newToken) {
        var cookies = ['node-tutorial-token=' + newToken.token.access_token + ';Max-Age=4000',
                       'node-tutorial-refresh-token=' + newToken.token.refresh_token + ';Max-Age=4000',
                       'node-tutorial-token-expires=' + newToken.token.expires_at.getTime() + ';Max-Age=4000'];
        response.setHeader('Set-Cookie', cookies);
        callback(null, newToken.token.access_token);
      }
    });
  } else {
    // Return cached token
    var access_token = getValueFromCookie('node-tutorial-token', request.headers.cookie);
    callback(null, access_token);
  }
}

Zum Schluss fügen wir die refreshAccessToken-Funktion zu authHelper.js hinzu.

refreshAccessToken in der Datei .\authHelper.js

function refreshAccessToken(refreshToken, callback) {
  var tokenObj = oauth2.accessToken.create({refresh_token: refreshToken});
  tokenObj.refresh(callback);
}

exports.refreshAccessToken = refreshAccessToken;

Verwenden der Mail-API

Da wir nun ein Zugriffstoken abrufen können, bietet es sich an, mit der Mail-API fortzufahren. Beginnen wir mit der Erstellung einer mail-Route und -Funktion. Öffnen Sie die Datei index.js, und aktualisieren Sie das handle-Array.

Aktualisiertes handle-Array in .\index.js

var handle = {};
handle['/'] = home;
handle['/authorize'] = authorize;
handle['/mail'] = mail;

Fügen Sie dann die mail-Funktion hinzu.

mail-Funktion in .\index.js

function mail(response, request) {
  getAccessToken(request, response, function(error, token) {
    console.log('Token found in cookie: ', token);
    var email = getValueFromCookie('node-tutorial-email', request.headers.cookie);
    console.log('Email found in cookie: ', email);
    if (token) {
      response.writeHead(200, {'Content-Type': 'text/html'});
      response.write('<p>Token retrieved from cookie: ' + token + '</p>');
      response.end();
    } else {
      response.writeHead(200, {'Content-Type': 'text/html'});
      response.write('<p> No token found in cookie!</p>');
      response.end();
    }
  });
}

Derzeit liest diese Funktion das Token lediglich aus dem Cookie und zeigt es an. Speichern Sie Ihre Änderungen, starten Sie den Server neu, und durchlaufen Sie den Anmeldevorgang erneut. Das Token sollte angezeigt werden. Da wir nun wissen, dass wir Zugriff auf das Token in der mail-Funktion haben, können wir die Mail-API aufrufen. Aktualisieren Sie die mail-Funktion so, dass der Posteingang abgefragt wird.

Neue Version der mail-Funktion in ./index.js

function mail(response, request) {
  getAccessToken(request, response, function(error, token) {
    console.log('Token found in cookie: ', token);
    var email = getValueFromCookie('node-tutorial-email', request.headers.cookie);
    console.log('Email found in cookie: ', email);
    if (token) {
      response.writeHead(200, {'Content-Type': 'text/html'});
      response.write('<div><h1>Your inbox</h1></div>');

      // Create a Graph client
      var client = microsoftGraph.Client.init({
        authProvider: (done) => {
          // Just return the token
          done(null, token);
        }
      });

      // Get the 10 newest messages
      client
        .api('/me/mailfolders/inbox/messages')
        .header('X-AnchorMailbox', email)
        .top(10)
        .select('subject,from,receivedDateTime,isRead')
        .orderby('receivedDateTime DESC')
        .get((err, res) => {
          if (err) {
            console.log('getMessages returned an error: ' + err);
            response.write('<p>ERROR: ' + err + '</p>');
            response.end();
          } else {
            console.log('getMessages returned ' + res.value.length + ' messages.');
            response.write('<table><tr><th>From</th><th>Subject</th><th>Received</th></tr>');
            res.value.forEach(function(message) {
              console.log('  Subject: ' + message.subject);
              var from = message.from ? message.from.emailAddress.name : 'NONE';
              response.write('<tr><td>' + from + 
                '</td><td>' + (message.isRead ? '' : '<b>') + message.subject + (message.isRead ? '' : '</b>') +
                '</td><td>' + message.receivedDateTime.toString() + '</td></tr>');
            });

            response.write('</table>');
            response.end();
          }
        });
    } else {
      response.writeHead(200, {'Content-Type': 'text/html'});
      response.write('<p> No token found in cookie!</p>');
      response.end();
    }
  });
}

Zusammenfassung des neuen Codes in der mail-Funktion:

  • Es wird ein Graph-Clientobjekt erstellt und initialisiert, um das an die Funktion übergebene Zugriffstoken zu verwenden.
  • Der X-AnchorMailbox-Header wird auf die Anforderung festgelegt, sodass der API-Endpunkt API-Aufrufe effizienter an den entsprechenden Back-End-Postfachserver weiterleiten kann. Aus diesem Grund haben wir uns die Mühe gemacht und zuvor die E-Mails des Benutzers abgerufen.
  • Die /me/mailfolders/inbox/messages-API wird aufgerufen, um die Posteingangsnachrichten abzurufen, und es werden weitere Methoden zum Steuern der Anforderung verwendet:
    • Die top-Methode wird mit dem Wert 10 verwendet, um die Ergebnisse auf die ersten 10 einzuschränken.
    • Die select-Methode wird verwendet, um nur die Eigenschaften subject, from, receivedDateTime und isRead anzufordern.
    • Die orderby-Methode wird mit dem Wert receivedDateTime desc verwendet, um die neuesten Nachrichten zuerst abzurufen.
  • Die Ergebnisse werden in einer Schleife durchlaufen, und Absender, Betreff und Datum/Uhrzeit des Nachrichtenempfangs werden ausgegeben.

Anzeigen der Ergebnisse

Speichern Sie die Änderungen, und melden Sie sich bei der App an. Nun sollte eine einfache Tabelle von Nachrichten in Ihrem Posteingang angezeigt werden.

Eine HTML-Tabelle mit dem Inhalt eines Posteingangs.

Hinzufügen von Kalender- und Kontakte-APIs

Da Sie nun das Aufrufen der Outlook-Mail-API gemeistert haben, dürfte es kein Problem mehr sein, das gleiche für Kalender- und Kontakte-APIs zu tun.

Tipp

Wenn Sie die Schritte in diesem Lernprogramm befolgt haben, haben Sie wahrscheinlich ein Zugriffstoken in Ihrem Sitzungscookie gespeichert. Dieses Token ist nur für den Mail.Read-Bereich gültig. Um die Kalender- oder Kontakte-API aufzurufen, müssen wir neue Bereiche hinzufügen. Starten Sie den Browser unbedingt neu, um das Sitzungscookie zu entfernen, damit Sie den Anmeldevorgang von vorne beginnen können, um ein neues Zugriffstoken zu erhalten.

Für die Kalender-API:

  1. Aktualisieren Sie das scopes-Array in authHelper.js, um den Calendars.Read-Bereich einzuschließen.

    // The scopes the app requires
    var scopes = [ 'openid',
                   'offline_access',
                   'User.Read',
                   'Mail.Read',
                   'Calendars.Read' ];
    
  2. Fügen Sie eine calendar-Route in index.js hinzu.

    handle['/calendar'] = calendar;
    
  3. Fügen Sie eine calendar-Funktion in index.js hinzu. Kopieren Sie den Code aus der mail-Funktion, und ersetzen Sie dabei die Aufrufe der Mail-API durch den folgenden Code.

    response.writeHead(200, {'Content-Type': 'text/html'});
    response.write('<div><h1>Your calendar</h1></div>');
    
    // Create a Graph client
    var client = microsoftGraph.Client.init({
      authProvider: (done) => {
        // Just return the token
        done(null, token);
      }
    });
    
    // Get the 10 events with the greatest start date
    client
      .api('/me/events')
      .header('X-AnchorMailbox', email)
      .top(10)
      .select('subject,start,end')
      .orderby('start/dateTime DESC')
      .get((err, res) => {
        if (err) {
          console.log('getEvents returned an error: ' + err);
          response.write('<p>ERROR: ' + err + '</p>');
          response.end();
        } else {
          console.log('getEvents returned ' + res.value.length + ' events.');
          response.write('<table><tr><th>Subject</th><th>Start</th><th>End</th><th>Attendees</th></tr>');
          res.value.forEach(function(event) {
            console.log('  Subject: ' + event.subject);
            response.write('<tr><td>' + event.subject + 
              '</td><td>' + event.start.dateTime.toString() +
              '</td><td>' + event.end.dateTime.toString() + '</td></tr>');
          });
    
          response.write('</table>');
          response.end();
        }
      });
    
  4. Starten Sie die App neu. Navigieren Sie nach der Anmeldung zu http://localhost:8000/calendar.

Für die Kontakte-API:

  1. Aktualisieren Sie das scopes-Array in authHelper.js, um den Contacts.Read-Bereich einzuschließen.

    // The scopes the app requires
    var scopes = [ 'openid',
                   'offline_access',
                   'User.Read',
                   'Mail.Read',
                   'Contacts.Read' ];
    
  2. Fügen Sie eine contacts-Route in index.js hinzu.

    handle['/contacts'] = contacts;
    
  3. Fügen Sie eine contacts-Funktion in index.js hinzu. Kopieren Sie den Code aus der mail-Funktion, und ersetzen Sie dabei die Aufrufe der Mail-API durch den folgenden Code.

    response.writeHead(200, {'Content-Type': 'text/html'});
    response.write('<div><h1>Your contacts</h1></div>');
    
    // Create a Graph client
    var client = microsoftGraph.Client.init({
      authProvider: (done) => {
        // Just return the token
        done(null, token);
      }
    });
    
    // Get the first 10 contacts in alphabetical order
    // by given name
    client
      .api('/me/contacts')
      .header('X-AnchorMailbox', email)
      .top(10)
      .select('givenName,surname,emailAddresses')
      .orderby('givenName ASC')
      .get((err, res) => {
        if (err) {
          console.log('getContacts returned an error: ' + err);
          response.write('<p>ERROR: ' + err + '</p>');
          response.end();
        } else {
          console.log('getContacts returned ' + res.value.length + ' contacts.');
          response.write('<table><tr><th>First name</th><th>Last name</th><th>Email</th></tr>');
          res.value.forEach(function(contact) {
            var email = contact.emailAddresses[0] ? contact.emailAddresses[0].address : 'NONE';
            response.write('<tr><td>' + contact.givenName + 
              '</td><td>' + contact.surname +
              '</td><td>' + email + '</td></tr>');
          });
    
          response.write('</table>');
          response.end();
        }
      });
    
  4. Starten Sie die App neu. Navigieren Sie nach der Anmeldung zu http://localhost:8000/contacts.