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!


All Rights Reserved