Authenticate and get messages Office 365 with Outlook Mail Rest API

Introduce

Installing

  • Install gem "oauth2"
  • Create controller Auth
  • Defining a function to generate the login URL
#File: app/helpers/auth_helper.rb
module AuthHelper
  # App client ID. Register the app in Azure AD to get this value.
  CLIENT_ID = "<YOUR CLIENT ID>"
  # App s client secret. Register the app in Azure AD to get this value.
  CLIENT_SECRET = "<YOUR CLIENT SECRET>"

  REDIRECT_URI = "http://localhost:3000/authorize"

  # 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/authorize",
                                token_url: "/common/oauth2/token"

    login_url = client.auth_code.authorize_url redirect_uri: REDIRECT_URI
  end
end

Generate a client ID and secret

  • Refer at here to create app in Azure AD and get app client ID and secret key. Replace the <YOUR CLIENT ID> and <YOUR CLIENT SECRET> placeholders with these values in app/helpers/auth_helper.rb file and save your changes.

Note

  • When create Azure AD, require you have Master Card or Visa. It is free trial for 30 days.
  • You should create user Mailboxes in Exchange Online for test. Follow here.

Back to coding

  • Now that we have actual values in the get_login_url function, let's put it to work.
  • You'll need to include the AuthHelper module to gain access to this function.
  • You can render get_login_url and see a result.

Example

# app/controllers/static_pages_controller.rb
class StaticPagesController < ApplicationController
  def home
    @login_url = get_login_url
  end
end

# app/views/static_pages/home.html.erb
<a href="<%= @login_url %>">Login and view my email</a>
  • Click on the link, you should be presented with a sign in page.
  • Sign in with your Office 365 account. Your browser should redirect to back to our app with a error (No route matches)

Exchanging the code for a token

  • Before update our code:
# config/routes.rb
Rails.application.routes.draw do
  root "static_pages#home"
  get "authorize" => "auth#gettoken"
end

#app/controllers/auth_controller.rb
class AuthController < ApplicationController
  def gettoken
    render text: params[:code]
  end
end
  • Replace REDIRECT_URI by authorize_url in auth_helper.rb.
  • Let's add another helper function to auth_helper.rb:
  def get_token_from_code auth_code
    client = OAuth2::Client.new CLIENT_ID,
                                CLIENT_SECRET,
                                site: "https://login.microsoftonline.com",
                                authorize_url: "/common/oauth2/authorize",
                                token_url: "/common/oauth2/token"
    token = client.auth_code.get_token auth_code,
                                       redirect_uri: authorize_url,
                                       resource: "https://outlook.office365.com"
    access_token = token.token
  end

  # Update app/controllers/auth_controller.rb file
  def gettoken
    def gettoken
      token = get_token_from_code params[:code]
      session[:azure_access_token] = token
      render text: "Access token saved in session cookie."
    end
  end

Using the Mail API

  • rails generate controller Mail index
  • Update version of gettoken action
def gettoken
  token = get_token_from_code params[:code]
  session[:azure_access_token] = token
  redirect_to mail_index_url
end

Make REST calls request to get messages from the inbox

# app/controllers/mail_controller.rb
class MailController < ApplicationController
  def index
    token = session[:azure_access_token]
    if token
      connect = Faraday.new url: "https://outlook.office365.com" do |faraday|
        faraday.response :logger
        faraday.adapter Faraday.default_adapter
      end

      response = connect.get do |request|
        request.url "/api/v1.0/me/messages?$orderby=DateTimeReceived&s$top=20"
        request.headers["Authorization"] = "Bearer #{token}"
        request.headers["Accept"] = "application/json"
      end
      @messages = JSON.parse(response.body)["value"]
      render json: @messages
    else
      redirect_to root_path
    end
  end
end

You can see messages of you display with json format. Please verify it.

!!!

Hopefully the article will be helpful for you. Thank you for reading!