require 'httparty' class MicrosoftGraph BASE_URL = 'https://graph.microsoft.com/v1.0'.freeze def initialize(current_user, client_id, client_secret, tenant_id, scopes) @current_user = current_user @uid = current_user.microsoft_user_id @token = current_user.microsoft_access_token @refresh_token = current_user.microsoft_refresh_token @token_expires_at = current_user.microsoft_token_expires_at @client_id = client_id @client_secret = client_secret @tenant_id = tenant_id @scopes = scopes end def create_teams_meeting(subject) # Obtain new token if token is expired or will expire in less than 5 minutes if 5.minutes.from_now.to_i > @token_expires_at.seconds refresh_access_token end response = HTTParty.post( "#{BASE_URL}/me/onlineMeetings", body: { subject: subject, participants: { organizer: { identity: { user: { id: @uid } } } } }.to_json, headers: { Authorization: "Bearer #{@token}", 'Content-Type': 'application/json' } ) raise StandardError, 'Authenticated user does not have a permission to create Teams Online Meeting' if response.code == 403 if response.code != 201 Rails.logger.error('[Microsoft Graph Error]') Rails.logger.error(response.inspect) raise StandardError, "Failed to create teams meeting [#{response.code}]" else JSON.parse(response.body) end end private def refresh_token_url "https://login.microsoftonline.com/#{@tenant_id}/oauth2/v2.0/token" end def refresh_access_token response = HTTParty.post(refresh_token_url, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: { client_id: @client_id, client_secret: @client_secret, refresh_token: @refresh_token, grant_type: 'refresh_token', scope: @scopes }) if response.code != 200 Rails.logger.error '[Microsoft Graph Error] Failed to obtain new access token using refresh token' Rails.logger.error(response.inspect) raise StandardError, 'Failed to obtain new access token' end parsed_response = JSON.parse(response.body) new_access_token = parsed_response['access_token'] new_refresh_token = parsed_response['refresh_token'] token_expires_in = parsed_response['expires_in'] # For how long access token is valid (in seconds) token_new_expiration_time = Time.now.to_i + token_expires_in @current_user.microsoft_access_token = new_access_token @current_user.microsoft_refresh_token = new_refresh_token @current_user.microsoft_token_expires_at = token_new_expiration_time @current_user.save! @token = new_access_token @refresh_token = new_refresh_token @token_expires_at = token_new_expiration_time end end