概要
前回 Outlook の API を実行してメールの一覧を取得するところまでやってみました
前回も参考にしたこのページが更新されみたいでやり方が変わっていました
なので再度試してみました
ハマリポイントもあったので紹介します
環境
- Windows7 64bit
- Ruby 2.2.4p230
- gem 2.4.8
- Rails 5.0.0
- Office365 API v2.0 (2016/08/18 時点)
MS アプリケーションポータルでアプリの作成
前回を参考にして作成してください
「アプリケーション ID」と「アプリケーションシークレット」の 2 つを取得できれば OK です
Rails アプリの作成
- rails new o365-tutorial
- cd o365-tutorial
- vim Gemfile
gem 'json'
gem 'oauth2'
gem 'activerecord-session_store'
gem 'faraday'
を追記して
- bundle install
- rails generate active_record:session_migration
- rails db:migrate
コーディングしていく
トップ画面の作成
- cd o365-tutorial
- vim app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
include AuthHelper
def home
login_url = get_login_url
render html: "<a href='#{login_url}'>Log in and view my calendar</a>".html_safe
end
end
- vim config/routes.rb
Rails.application.routes.draw do
root 'application#home'
get 'authorize' => 'auth#gettoken'
get 'calendar/index'
end
認証部分の作成
- cd o365-tutorial
- rails generate controller Auth
- vim app/helpers/auth_helper.rb
module AuthHelper
CLIENT_ID = 'be0c3ce7-1379-45b9-830a-9960c8656b30'
CLIENT_SECRET = 'Tkp******************************'
SCOPES = [ 'openid',
'offline_access',
'https://outlook.office.com/calendars.read' ]
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
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
def get_user_email(access_token)
conn = Faraday.new(:url => 'https://outlook.office.com') do |faraday|
# Outputs to the console
faraday.response :logger
# Uses the default Net::HTTP adapter
faraday.adapter Faraday.default_adapter
end
response = conn.get do |request|
request.url 'api/v2.0/Me'
request.headers['Authorization'] = "Bearer #{access_token}"
request.headers['Accept'] = 'application/json'
end
email = JSON.parse(response.body)['EmailAddress']
end
def get_access_token(token_hash)
# Get the current token hash from session
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)
if token.expired?
new_token = token.refresh!
session[:azure_token] = new_token.to_hash
access_token = new_token.token
else
access_token = token.token
end
end
end
CLIENT_ID, CLIENT_SECRET の部分はアプリポータルで取得したアプリケーション ID とアプリケーションシークレットを入力してください
- vim app/controllers/auth_controller.rb
class AuthController < ApplicationController
$token = {}
def gettoken
token = get_token_from_code params[:code]
$token = token.to_hash
session[:user_email] = get_user_email token.token
redirect_to calendar_index_url
end
end
Office365 の OAuth 認証を実行して取得できたトークン情報をグローバル変数に格納しています
サンプルでは session オブジェクトに格納していたのですが、session に 4092bytes 以上のデータを保存しようとするとエラーになるので「ActionDispatch::Cookies::MAX_COOKIE_SIZE = 8192」という感じで無理矢理保存してみたのですが、これもダメだったのでグローバル変数を定義しました
おそらくあまり良いやり方ではないですが、とりあえず動かすのが目的だったのでグローバル変数を使いました
カレンダーの一覧を表示する部分の作成
- cd o365-tutorial
- rails generate controller Calendar index
- vim app/controllers/calendar_controller.rb
class CalendarController < ApplicationController
include AuthHelper
def index
token = get_access_token($token)
email = session[:user_email]
if token
conn = Faraday.new(:url => 'https://outlook.office.com') do |faraday|
faraday.response :logger
faraday.adapter Faraday.default_adapter
end
response = conn.get do |request|
# request.url '/api/v2.0/Me/Events?$orderby=Start/DateTime asc&$select=Subject,Start,End&$top=10'
request.url '/api/v2.0/Me/Events?$orderby=Start/DateTime desc&$select=Subject,Start,End&$top=10'
request.headers['Authorization'] = "Bearer #{token}"
request.headers['Accept'] = "application/json"
request.headers['X-AnchorMailbox'] = email
end
@events = JSON.parse(response.body)['value']
else
redirect_to root_url
end
end
end
- vim app/views/calendar/index.html.erb
<h1>My events</h1>
<table>
<tr>
<th>Subject</th>
<th>Start</th>
<th>End</th>
</tr>
<% @events.each do |event| %>
<tr>
<td><%= event['Subject'] %></td>
<td><%= event['Start'] %></td>
<td><%= event['End'] %></td>
</tr>
<% end %>
</table>
動作確認
- cd o365-tutorial
- rails server –bind=0.0.0.0
http://localhost:3000/ にブラウザでアクセスします
ログインリンクがあるのでログインすると最新のカレンダーに登録された予定の一覧が表示されるはずです
最後に
Office365 の API を使ってカレンダーの予定を取得してみました
日付は UTC で取得できるので localization してください
あとは自分以外の予定の取得とか予定の登録とかもできるようになるとアプリを作れる技術は揃いそうです
0 件のコメント:
コメントを投稿