Skip to content

Instantly share code, notes, and snippets.

@jagdeepsingh
Last active June 24, 2016 13:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jagdeepsingh/2b1e8f691d5ce062456b to your computer and use it in GitHub Desktop.
Save jagdeepsingh/2b1e8f691d5ce062456b to your computer and use it in GitHub Desktop.
Ruby service for Microsoft Outlook calendar API
class OutlookCalendarService
APP_ID = your_app_id
APP_SECRET = your_app_secret
LOGIN_API_DOMAIN = 'https://login.microsoftonline.com'
AUTHORIZE_PATH = '/common/oauth2/v2.0/authorize'
TOKEN_PATH = '/common/oauth2/v2.0/token'
CALENDAR_API_DOMAIN = 'https://outlook.office365.com'
VERSION_PATH = '/api/v2.0'
SCOPES = ['openid', 'https://outlook.office.com/Calendars.ReadWrite']
attr_reader :callback_url
def initialize(callback_url)
@callback_url = callback_url
end
def login_url
auth_code.authorize_url(redirect_uri: callback_url, scope: scopes)
end
def auth(code)
auth_code.get_token(code, redirect_uri: callback_url, scope: scopes)
end
def email(auth)
decoded_token(auth)['preferred_username']
end
def create_event(token, attributes = {})
url = "#{ CALENDAR_API_DOMAIN }#{ VERSION_PATH }/me/events"
headers = create_event_headers(token)
body = create_event_attributes(attributes)
do_post_request(url, headers, body)
end
private
def oauth_client
@oauth_client ||= OAuth2::Client.new(APP_ID,
APP_SECRET,
site: LOGIN_API_DOMAIN,
authorize_url: AUTHORIZE_PATH,
token_url: TOKEN_PATH)
end
def auth_code
oauth_client.auth_code
end
def scopes
SCOPES.join(' ')
end
def encoded_token(auth)
id_token = auth.params['id_token']
token_parts = id_token.split('.')
encoded_token = token_parts[1]
leftovers = token_parts[1].length.modulo(4)
if leftovers == 2
encoded_token += '=='
elsif leftovers == 3
encoded_token += '='
end
encoded_token
end
def decoded_token(auth)
decoded_token = Base64.urlsafe_decode64(encoded_token(auth))
JSON.parse(decoded_token)
end
def create_event_headers(token)
{ 'Authorization' => "Bearer #{ token }",
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'User-Agent' => 'Vesper',
'client-request-id' => rand(100000..999999),
'return-client-request-id' => 'true' }
end
def create_event_attributes(attributes)
{ 'Subject' => attributes[:summary],
'Body' => { 'ContentType' => 'HTML', 'Content' => attributes[:description] },
'Start' => { 'DateTime' => attributes[:start_at], 'TimeZone' => attributes[:time_zone] },
'End' => { 'DateTime' => attributes[:end_at], 'TimeZone' => attributes[:time_zone] },
'Attendees' => attributes[:attendees_emails].map { |email| { 'EmailAddress' => { 'Address' => email }, 'Type' => 'Required' } } }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment