Schreiben einer Ruby on Rails-App zum Abrufen von Outlook-Mail, -Kalender und -Kontakten

In diesem Leitfaden werden Sie schrittweise durch den Prozess des Erstellens einer einfachen Ruby on Rails-App zum Zugreifen auf Benutzerdaten 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 Ruby on Rails bereits installiert haben und auf Ihrem Entwicklungscomputer ausführen.

Erstellen der App

Wechseln Sie über die Befehlszeile zum Verzeichnis, in dem Sie Ihre neue Ruby on Rails-App erstellen möchten. Führen Sie den folgenden Befehl aus, um eine App mit dem Namen o365-tutorial zu erstellen.

Hinweis

Sie können den Namen beliebig ändern. Für die Zwecke dieses Leitfadens gehe ich davon aus, dass der Name der App o365-tutorial ist.

rails new o365-tutorial

Wenn Sie mit Ruby on Rails vertraut sind, ist dies nichts Neues für Sie. Wenn Sie noch nicht mit Ruby on Rails vertraut sind, werden Sie bemerken, dass mit dem Befehl ein o365-tutorial-Unterverzeichnis erstellt wird, das eine Anzahl von Dateien und Verzeichnissen enthält. Die meisten davon sind nicht wichtig für unsere Zwecke, machen Sie sich also nicht zu viele Gedanken darüber.

Ändern Sie in der Befehlszeile Ihr Verzeichnis zum o365-tutorial-Unterverzeichnis. Stellen wir noch kurz sicher, dass die App erfolgreich erstellt wurde. Führen Sie den folgenden Befehl aus:

rails server

Öffnen Sie einen Browser, und navigieren Sie zu http://localhost:3000. Es sollte die standardmäßige Startseite von Ruby on Rails angezeigt werden.

Standardmäßige Startseite von Ruby on Rails.

Da wir nun sichergestellt haben, dass Ruby on Rails 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 ändern wir das Layout, das von allen Seiten in der App zum Hinzufügen von Bootstrap für das grundlegende Layout und die Formatierung und einer einfachen Navigationsleiste verwendet wird. Öffnen Sie die Datei .\o365-tutorial\app\views\layouts\application.html.erb im bevorzugten Editor, und ersetzen Sie den Inhalt durch den folgenden Code.

Inhalt der Datei .\o365-tutorial\app\views\layouts\application.html.erb

<!DOCTYPE html>
<html>
<head>
  <title>O365Tutorial</title>
  <!-- Latest compiled and minified CSS -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

  <!-- Optional theme -->
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
  <%= stylesheet_link_tag    'application', media: 'all', 'data-turbolinks-track' => true %>
  <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
  <%= csrf_meta_tags %>
</head>
<body>
  <nav class="navbar navbar-inverse navbar-fixed-top">
    <div class="container">
      <div class="navbar-header">
        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
          <span class="sr-only">Toggle navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="#">Outlook Ruby Sample</a>
      </div>
      <div id="navbar" class="navbar-collapse collapse">
        <ul class="nav navbar-nav authed-nav">
          <li id='home-nav'><a href="/">Home</a></li>
          <li id='inbox-nav'><a href="/mail/index">Inbox</a></li>
          <li id='calendar-nav'><a href="/calendar/index">Calendar</a></li>
          <li id='contacts-nav'><a href="/contacts/index">Contacts</a></li>
        </ul>
      </div>
    </div>
  </nav>

  <div class="container main-container">
<%= yield %>
  </div>

</body>
</html>

Im Folgenden werden einige kleine Änderungen an der CSS-Datei der Anwendung vorgenommen, um die hinzugefügte Navigationsleiste anzupassen. Öffnen Sie die Datei .\o365-tutorial\app\assets\stylesheets\application.css, und fügen Sie den folgenden Code hinzu.

Der Code ist in der Datei .\o365-tutorial\app\assets\stylesheets\application.css vorhanden.

body {
  padding-top: 70px;
}

Ersetzen Sie nun die standardmäßige Startseite durch eine eigene Seite. Dazu wird ein neuer Controller für die Startseite erstellt. Führen Sie in der Befehlszeile den folgenden Befehl aus:

rails generate controller Home

Wenn dieser Befehl abgeschlossen ist, erstellen Sie eine neue Datei in dem .\o365-tutorial\app\views\home-Verzeichnis namens index.html.erb. Fügen Sie den folgenden Code ein.

Inhalt der Datei .\o365-tutorial\app\views\home\index.html.erb

<div class="jumbotron">
  <h1>Outlook Ruby Sample</h1>
  <p>This example shows how to get an OAuth token from Azure using the <a href="https://docs.microsoft.com/de-de/azure/active-directory/develop/active-directory-v2-protocols-oauth-code" target="_blank">authorization code grant flow</a> and to use that token to make calls to the Outlook APIs.</p>
  <p>
    <a class="btn btn-lg btn-primary" href="<%= @login_url %>" role="button" id="connect-button">Connect to Outlook</a>
  </p>
</div>

Wie Sie sehen, ist unsere Startseite sehr einfach. Im Moment führt der Link noch keine Aktion aus, das werden wir aber bald ändern. Zuerst müssen wir Rails mitteilen, dass diese Aktion ausgelöst werden soll. Dazu müssen wir eine Route definieren. Öffnen Sie die Datei .\o365-tutorial\config\routes.rb, und legen Sie die standardmäßige Route (oder „Stamm“) auf die index-Aktion des home-Controllers fest, die wir gerade erstellt haben.

Inhalt der Datei .\o365-tutorial\config\routes.rb

Rails.application.routes.draw do
  root 'home#index'
end

Speichern Sie Ihre Änderungen. Beim Aufrufen von http://localhost:3000 sollte nun Folgendes angezeigt werden:

Startseite der App.

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 o365-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:3000/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 den Gem oauth2 für das Verarbeiten unserer OAuth-Anforderungen. Des Weiteren verwenden wir den Gem activerecord-session_store zum Speichern unserer Sitzungen in einer Datenbank. Öffnen Sie ./o365-tutorial/GemFile, und fügen Sie die folgenden Zeilen an einer beliebigen Stelle in dieser Datei hinzu:

gem 'oauth2'
gem 'activerecord-session_store'

Speichern Sie die Datei, und führen Sie den folgenden Befehl aus (starten Sie anschließend den Rails-Server neu):

bundle install

Im Folgenden wird die App für die Verwendung des activerecord-session_store-Gem für den Sitzungsspeicher konfiguriert. Grund hierfür ist, dass der standardmäßige Cookiespeicher auf 4 KB Daten beschränkt ist, was nicht für das Speichern der Token ausreicht, die wir von Azure erhalten.

Öffnen Sie die Datei .\o365-tutorial\config\initializers\session_store.rb. Ersetzen Sie den Text :cookie_store mit :active_record_store.

Geben Sie in der Befehlszeile die folgenden Befehle ein, um die Sitzungsdatenbank zu erstellen.

rails generate active_record:session_migration
rails db:migrate

Aufgrund der Art des OAuth2-Flusses ist es sinnvoll, einen Controller zum Verarbeiten der Umleitungen aus Azure zu erstellen. Führen Sie den folgenden Befehl aus, um einen Controller mit dem Namen Auth zu generieren:

rails generate controller Auth

Öffnen Sie die Datei .\o365-tutorial\app\helpers\auth_helper.rb. Wir beginnen, indem wir zunächst eine Funktion zum Generieren der Anmelde-URL definieren.

Inhalt der Datei .\o365-tutorial\app\helpers\auth_helper.rb

module AuthHelper

  # App's client ID. Register the app in Application Registration Portal to get this value.
  CLIENT_ID = '<YOUR APP ID HERE>'
  # App's client secret. Register the app in Application Registration Portal to get this value.
  CLIENT_SECRET = '<YOUR APP PASSWORD HERE>'

  # Scopes required by the app
  SCOPES = [ 'openid',
             'profile',
             'User.Read',
             'Mail.Read' ]

  REDIRECT_URI = 'http://localhost:3000/authorize' # Temporary!

  # Generates the login URL for the app.
  def get_login_url
    client = OAuth2::Client.new(CLIENT_ID,
                                CLIENT_SECRET,
                                :site => 'https://login.microsoftonline.com',
                                :authorize_url => '/common/oauth2/v2.0/authorize',
                                :token_url => '/common/oauth2/v2.0/token')

    login_url = client.auth_code.authorize_url(:redirect_uri => REDIRECT_URI, :scope => SCOPES.join(' '))
  end
end

Als Erstes definieren wir die Client-ID und den geheimen Clientschlüssel sowie die Berechtigungsbereiche, die unsere App erfordert. Wir werden einen Umleitungs-URI als hartcodierten Wert definieren. Wir werden später weitere Verbesserungen daran vornehmen, für unsere Zwecke reicht es jedoch aus.

Ersetzen Sie die Platzhalter <YOUR APP ID HERE> und <YOUR APP PASSWORD HERE> durch die Werte, die Sie in Schritt 3 generiert haben, und speichern Sie die Änderungen.

Nachdem wir die get_login_url-Funktion implementiert haben, können wir mit dieser arbeiten. Öffnen Sie die Datei .\o365-tutorial\app\controllers\home_controller.rb, und ersetzen Sie den Inhalt durch den folgenden Code:

Aktualisierter Inhalt der Datei .\o365-tutorial\app\controllers\home_controller.rb

class HomeController < ApplicationController
  include AuthHelper

  def index
    # Display the login link.
    @login_url = get_login_url
  end
end

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

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

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

No route matches [GET] "/authorize"

Wenn Sie auf der Fehlerseite von Rails nach unten scrollen, werden die Anforderungsparameter angezeigt, die den Autorisierungscode enthalten.

Parameters:
{"code"=>"M2ff0cb19-ec9d-db94-c5ab-4c634e319315"}

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. Rails hat uns gezeigt, dass wird den Autorisierungscode in der Anforderung erneut erhalten. Wir sind also auf dem richtigen Weg. 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 zu routes.rb hinzu.

Aktualisierter Inhalt der Datei .\o365-tutorial\config\routes.rb

Rails.application.routes.draw do
  root 'application#home'
  get 'authorize' => 'auth#gettoken'
end

Die hinzugefügte Zeile gibt Rails an, dass wenn eine GET-Anforderung für /authorize hereinkommt, die gettoken-Aktion auf dem auth-Controller ausgelöst wird. Damit dies funktioniert, müssen wir also diese Aktion implementieren. Öffnen Sie die Datei .\o365-tutorial\app\controllers\auth_controller.rb, und definieren Sie die gettoken-Aktion.

Inhalt der Datei .\o365-tutorial\app\controllers\auth_controller.rb

class AuthController < ApplicationController

  def gettoken
    render text: params[:code]
  end
end

Im Folgenden nehmen wir eine letzte Verfeinerung vor, bevor wir diesen neuen Code verwenden. Da wir nun über eine Route für den Umleitungs-URI verfügen, können wir die hartcodierte Konstante in auth_helper.rb und stattdessen den folgenden Rails-Namen für die Route verwenden: authorize_url.

Aktualisierter Inhalt der Datei .\o365-tutorial\app\helpers\auth_helper.rb

module AuthHelper

  # App's client ID. Register the app in Application Registration Portal to get this value.
  CLIENT_ID = '<YOUR APP ID HERE>'
  # App's client secret. Register the app in Application Registration Portal to get this value.
  CLIENT_SECRET = '<YOUR APP PASSWORD HERE>'

  # Scopes required by the app
  SCOPES = [ 'openid',
             'profile',
             'User.Read',
             'Mail.Read' ]

  # Generates the login URL for the app.
  def get_login_url
    client = OAuth2::Client.new(CLIENT_ID,
                                CLIENT_SECRET,
                                :site => "https://login.microsoftonline.com",
                                :authorize_url => "/common/oauth2/v2.0/authorize",
                                :token_url => "/common/oauth2/v2.0/token")

    login_url = client.auth_code.authorize_url(:redirect_uri => authorize_url, :scope => SCOPES.join(' '))
  end
end

Aktualisieren Sie Ihren Browser (oder wiederholen Sie den Anmeldevorgang). Anstelle einer Rails-Fehlerseite 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 get_token_from_code zu auth_helper.rb hinzu.

get_token_from_code in der Datei .\o365-tutorial\app\helpers\auth_helper.rb

# Exchanges an authorization code for a token
def get_token_from_code(auth_code)
  client = OAuth2::Client.new(CLIENT_ID,
                              CLIENT_SECRET,
                              :site => 'https://login.microsoftonline.com',
                              :authorize_url => '/common/oauth2/v2.0/authorize',
                              :token_url => '/common/oauth2/v2.0/token')

  token = client.auth_code.get_token(auth_code,
                                     :redirect_uri => authorize_url,
                                     :scope => SCOPES.join(' '))
end

Abrufen der E-Mail-Adresse des Benutzers

Wir verwenden das Zugriffstoken das erste Mal, um die E-Mail-Adresse des Benutzers aus Graph abzurufen. Sie werden bald sehen, warum wir das tun. Beginnen wir damit, die Microsoft Graph-Clientbibliothek für Ruby herunterzuladen. Wir verwenden diesen Gem für alle Outlook-bezogenen Anforderungen.

Öffnen Sie die Datei Gemfile, und fügen Sie diese Zeile an einer beliebigen Stelle in der Datei hinzu:

gem 'microsoft_graph'

Speichern Sie die Datei, führen Sie bundle install aus, und starten Sie den Server neu.

Fügen Sie eine neue get_user_email-Funktion zu auth_helper.rb hinzu.

get_user_email in der Datei .\o365-tutorial\app\helpers\auth_helper.rb

# Gets the user's email from the /Me endpoint
def get_user_email(access_token)
  callback = Proc.new { |r| r.headers['Authorization'] = "Bearer #{access_token}"}

  graph = MicrosoftGraph.new(base_url: 'https://graph.microsoft.com/v1.0',
                             cached_metadata_file: File.join(MicrosoftGraph::CACHED_METADATA_DIRECTORY, 'metadata_v1.0.xml'),
                             &callback)

  me = graph.me
  email = me.mail
end

Nun möchten wir sicherstellen, dass diese funktioniert. Ändern Sie die gettoken-Aktion in der Datei auth_controller.rb so, dass die folgenden Hilfsfunktionen verwendet und die Rückgabewerte angezeigt werden.

Aktualisierter Inhalt der Datei .\o365-tutorial\app\controllers\auth_controller.rb

class AuthController < ApplicationController

  def gettoken
  token = get_token_from_code params[:code]
  email = get_user_email token.token
  render text: "Email: #{email}, TOKEN: #{token.token}"
  end
end

Wenn Sie Ihre Änderungen speichern und den Anmeldevorgang erneut durchlaufen, sollte die E-Mail-Adresse des Benutzers gefolgt von einer langen 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 gettoken-Aktion

def gettoken
  token = get_token_from_code params[:code]
  session[:azure_token] = token.to_hash
  session[:user_email] = get_user_email token.token
  render text: "Access token saved in session cookie."
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 auth_helper.rb hinzu:

# Scopes required by the app
SCOPES = [ 'openid',
           'profile',
           'offline_access',
           'User.Read',
           'Mail.Read' ]

Dies bewirkt, dass die Tokenantwort von Azure ein Aktualisierungstoken enthält. Fügen Sie nun eine Hilfsmethode in auth_helper.rb zum Abrufen des zwischengespeicherten Tokens, überprüfen Sie, ob dieses abgelaufen ist, und aktualisieren Sie es, falls erforderlich.

get_access_token in der Datei .\o365-tutorial\app\helpers\auth_helper.rb

# Gets the current access token
def get_access_token
  # Get the current token hash from session
  token_hash = session[:azure_token]

  client = OAuth2::Client.new(CLIENT_ID,
                              CLIENT_SECRET,
                              :site => 'https://login.microsoftonline.com',
                              :authorize_url => '/common/oauth2/v2.0/authorize',
                              :token_url => '/common/oauth2/v2.0/token')

  token = OAuth2::AccessToken.from_hash(client, token_hash)

  # Check if token is expired, refresh if so
  if token.expired?
    new_token = token.refresh!
    # Save new token
    session[:azure_token] = new_token.to_hash
    access_token = new_token.token
  else
    access_token = token.token
  end
end

Verwenden der Mail-API

Da wir nun ein Zugriffstoken abrufen können, bietet es sich an, mit der Mail-API fortzufahren. Beginnen wir mit dem Erstellen eines Controllers für E-Mail-Vorgänge.

rails generate controller Mail index

Dies weicht etwas von der Vorgehensweise beim Erstellen des Auth-Controllers ab. Diesmal haben wir den Namen einer Aktion übergeben, nämlich index. Rails fügt automatisch eine Route für diese Aktion hinzu und generiert eine Ansichtsvorlage.

Nun können wir die gettoken-Aktion zum letzten Mal für die Umleitung zu der Indexaktion im E-Mail-Controller ändern.

Neue Version der gettoken-Aktion

def gettoken
  token = get_token_from_code params[:code]
  session[:azure_token] = token.to_hash
  session[:user_email] = get_user_email token.token
  redirect_to mail_index_url
end

Nun werden Sie beim Durchlaufen des Anmeldevorgangs in der App zu der Seite http://localhost:3000/mail/index weitergeleitet. Auf dieser Seite passiert nichts, also sollten wir dies beheben.

Öffnen Sie die Datei .\o365-tutorial\app\controllers\mail_controller.rb, und definieren Sie die index-Aktion:

Inhalt der Datei .\o365-tutorial\app\controllers\mail_controller.rb

class MailController < ApplicationController

  include AuthHelper

  def index
    token = get_access_token
    email = session[:user_email]

    if token
      # If a token is present in the session, get messages from the inbox
      callback = Proc.new do |r| 
        r.headers['Authorization'] = "Bearer #{token}"
        r.headers['X-AnchorMailbox'] = email
      end

      graph = MicrosoftGraph.new(base_url: 'https://graph.microsoft.com/v1.0',
                                 cached_metadata_file: File.join(MicrosoftGraph::CACHED_METADATA_DIRECTORY, 'metadata_v1.0.xml'),
                                 &callback)

      @messages = graph.me.mail_folders.find('inbox').messages.order_by('receivedDateTime desc')
    else
      # If no token, redirect to the root url so user
      # can sign in.
      redirect_to root_url
    end
  end
end

Zusammenfassung des Codes in der index-Aktion:

  • Es wird ein Graph-Client erstellt.
  • Er gibt eine GET-Anforderung an die URL für die Nachrichten im Posteingang mit den folgenden Merkmalen aus:
    • Er verwendet die order_by-Methode zum Sortieren der Ergebnisse nach receivedDateTime.
    • Er legt den Authorization-Header für die Verwendung des Zugriffstokens aus Azure fest.
    • Er legt den X-AnchorMailbox-Header auf die E-Mail-Adresse des Benutzers fest. Durch Festlegen dieses Headers kann der API-Endpunkt API-Aufrufe effizienter an den entsprechenden Back-End-Postfachserver weiterleiten.
  • Er speichert die zurückgegebene Sammlung in der @messages-Variablen. Diese Variable ist in der Ansichtsvorlage verfügbar.

Anzeigen der Ergebnisse

Nun müssen wir die der index-Aktion zugeordnete Ansichtsvorlage für die Verwendung der @messages-Variablen geändert. Öffnen Sie die Datei .\o365-tutorial\app\views\mail\index.html.erb, und ersetzen Sie den Inhalt durch Folgendes:

Inhalt der Datei .\o365-tutorial\app\views\mail\index.html.erb

<h1>My messages</h1>
<table class="table">
  <tr>
    <th>From</th>
    <th>Subject</th>
    <th>Received</th>
  </tr>
  <% @messages.each do |message| %>
    <tr>
      <td><%= message.from.email_address.name %></td>
      <td><%= message.subject %></td>
      <td><%= message.received_date_time %></td>
    </tr>
  <% end %>
</table>

Die Vorlage ist eine einfache HTML-Tabelle. Sie verwendet eingebetteten Ruby-Code zum Durchlaufen der Ergebnisse in der @messages-Variablen, die wir in der index-Aktion festgelegt haben, und zum Erstellen einer Tabellenzeile für jede Nachricht. Die Syntax für den Zugriff auf die Werte der einzelnen Nachrichten ist einfach.

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 auth_helper.rb, um den Calendars.Read-Bereich einzuschließen.

    # Scopes required by the app
    SCOPES = [ 'openid',
               'profile',
               'offline_access',
               'User.Read',
               'Mail.Read',
               'Calendars.Read' ]
    
  2. Generieren Sie einen Calendar-Controller.

    rails generate controller Calendar index
    
  3. Öffnen Sie die Datei .\o365-tutorial\app\controllers\calendar_controller.rb, und fügen Sie den folgenden Code hinzu.

    class CalendarController < ApplicationController
    
      include AuthHelper
    
      def index
        token = get_access_token
        email = session[:user_email]
        if token
          # If a token is present in the session, get events from the calendar
          callback = Proc.new do |r| 
            r.headers['Authorization'] = "Bearer #{token}"
            r.headers['X-AnchorMailbox'] = email
          end
    
          graph = MicrosoftGraph.new(base_url: 'https://graph.microsoft.com/v1.0',
                                    cached_metadata_file: File.join(MicrosoftGraph::CACHED_METADATA_DIRECTORY, 'metadata_v1.0.xml'),
                                    &callback)
    
          @events = graph.me.events.order_by('start/dateTime asc')
        else
          # If no token, redirect to the root url so user
          # can sign in.
          redirect_to root_url
        end
      end
    end
    
  4. Öffnen Sie die Datei .\o365-tutorial\app\views\calendar\index.html.erb, und fügen Sie den folgenden Code hinzu.

    <h1>My events</h1>
    <table class="table">
      <tr>
        <th>Subject</th>
        <th>Start</th>
        <th>End</th>
      </tr>
      <% @events.each do |event| %>
        <tr>
          <td><%= event.subject %></td>
          <td><%= event.start.date_time %></td>
          <td><%= event.end.date_time %></td>
        </tr>
      <% end %>
    </table>
    

Für die Kontakte-API:

  1. Aktualisieren Sie das SCOPES-Array in auth_helper.rb, um den Calendars.Read-Bereich einzuschließen.

    # Scopes required by the app
    SCOPES = [ 'openid',
               'profile',
               'offline_access',
               'User.Read',
               'Mail.Read',
               'Contacts.Read' ]
    
  2. Generieren Sie einen Contacts-Controller.

    rails generate controller Contacts index
    
  3. Öffnen Sie die Datei .\o365-tutorial\app\controllers\contacts_controller.rb, und fügen Sie den folgenden Code hinzu.

    class ContactsController < ApplicationController
    
      include AuthHelper
    
      def index
        token = get_access_token
        email = session[:user_email]
        if token
          # If a token is present in the session, get contacts
          callback = Proc.new do |r| 
            r.headers['Authorization'] = "Bearer #{token}"
            r.headers['X-AnchorMailbox'] = email
          end
    
          graph = MicrosoftGraph.new(base_url: 'https://graph.microsoft.com/v1.0',
                                    cached_metadata_file: File.join(MicrosoftGraph::CACHED_METADATA_DIRECTORY, 'metadata_v1.0.xml'),
                                    &callback)
    
          @contacts = graph.me.contacts.order_by('givenName asc')
        else
          # If no token, redirect to the root url so user
          # can sign in.
          redirect_to root_url
        end
      end
    end
    
  4. Öffnen Sie die Datei .\o365-tutorial\app\views\contacts\index.html.erb, und fügen Sie den folgenden Code hinzu.

    <h1>My contacts</h1>
    <table class="table">
      <tr>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Email</th>
      </tr>
      <% @contacts.each do |contact| %>
        <tr>
          <td><%= contact.given_name %></td>
          <td><%= contact.surname %></td>
          <td><%= contact.email_addresses[0].address %></td>
        </tr>
      <% end %>
    </table>