From aff901377952baec6fbc7b835b3fc065428a0585 Mon Sep 17 00:00:00 2001 From: Stefan Wienert Date: Tue, 17 Aug 2021 10:18:56 +0200 Subject: [PATCH 1/9] Refac: common function extracted; Feat: Places + Users + GetSchedule added --- lib/ms_graph_rest.rb | 86 ++++++++++++++----- lib/ms_graph_rest/calendar_create_event.rb | 70 +++++++++++++++ lib/ms_graph_rest/calendar_get_schedule.rb | 42 +++++++++ lib/ms_graph_rest/calendar_groups.rb | 22 +++++ lib/ms_graph_rest/calendar_view.rb | 64 ++------------ lib/ms_graph_rest/calendars.rb | 28 ++++++ lib/ms_graph_rest/chainable_action.rb | 73 ++++++++++++++++ lib/ms_graph_rest/find_rooms.rb | 21 +++++ lib/ms_graph_rest/modifying_action.rb | 13 +++ lib/ms_graph_rest/places.rb | 17 ++++ lib/ms_graph_rest/response.rb | 25 ++++++ lib/ms_graph_rest/response_with_pagination.rb | 43 ++++++++++ lib/ms_graph_rest/users.rb | 65 ++------------ 13 files changed, 433 insertions(+), 136 deletions(-) create mode 100644 lib/ms_graph_rest/calendar_create_event.rb create mode 100644 lib/ms_graph_rest/calendar_get_schedule.rb create mode 100644 lib/ms_graph_rest/calendar_groups.rb create mode 100644 lib/ms_graph_rest/calendars.rb create mode 100644 lib/ms_graph_rest/chainable_action.rb create mode 100644 lib/ms_graph_rest/find_rooms.rb create mode 100644 lib/ms_graph_rest/modifying_action.rb create mode 100644 lib/ms_graph_rest/places.rb create mode 100644 lib/ms_graph_rest/response.rb create mode 100644 lib/ms_graph_rest/response_with_pagination.rb diff --git a/lib/ms_graph_rest.rb b/lib/ms_graph_rest.rb index 4e13040..c4755cf 100644 --- a/lib/ms_graph_rest.rb +++ b/lib/ms_graph_rest.rb @@ -3,17 +3,23 @@ require 'multi_json' require_relative 'ms_graph_rest/version' -require_relative 'ms_graph_rest/mails' -require_relative 'ms_graph_rest/error' -require_relative 'ms_graph_rest/users' -require_relative 'ms_graph_rest/subscriptions' +require_relative 'ms_graph_rest/calendar_create_event' +require_relative 'ms_graph_rest/calendar_get_schedule' +require_relative 'ms_graph_rest/calendar_groups' require_relative 'ms_graph_rest/calendar_view' +require_relative 'ms_graph_rest/calendars' +require_relative 'ms_graph_rest/error' +require_relative 'ms_graph_rest/find_rooms' +require_relative 'ms_graph_rest/groups' +require_relative 'ms_graph_rest/mails' require_relative 'ms_graph_rest/messages' require_relative 'ms_graph_rest/photos' -require_relative 'ms_graph_rest/groups' +require_relative 'ms_graph_rest/places' require_relative 'ms_graph_rest/planner_tasks' -require_relative 'ms_graph_rest/todo_lists' +require_relative 'ms_graph_rest/subscriptions' require_relative 'ms_graph_rest/todo_list_tasks' +require_relative 'ms_graph_rest/todo_lists' +require_relative 'ms_graph_rest/users' class Faraday::FileReadAdapter < Faraday::Adapter def self.folder=(val) @@ -70,23 +76,24 @@ def self.fake_folder=(val) end class BaseConnection - attr_reader :access_token + attr_reader :access_token, :version - def initialize(access_token:) + def initialize(access_token:, version: 'v1.0') @access_token = access_token.to_str.clone.freeze + @version = version end end class FaradayConnection < BaseConnection attr_reader :faraday_adapter - def initialize(access_token:, faraday_adapter:) - super(access_token: access_token) + def initialize(access_token:, faraday_adapter:, version: 'v1.0') + super(access_token: access_token, version: version) @faraday_adapter = faraday_adapter end def conn - @conn ||= Faraday.new(url: 'https://graph.microsoft.com/v1.0/', + @conn ||= Faraday.new(url: "https://graph.microsoft.com/#{@version}/", headers: { 'Content-Type' => 'application/json' }) do |c| c.use Faraday::Response::RaiseError c.authorization :Bearer, access_token @@ -96,24 +103,28 @@ def conn end end - def get_raw(path, params) - conn.get(path, params) + def get_raw(path, params, headers = {}) + conn.get(path, params, headers) rescue Faraday::Error => e raise MsGraphRest.wrap_request_error(e) end - def get(path, params) - response = get_raw(path, params) + # @param consistencylevel [String] "eventual" + def get(path, params, consistencylevel: nil, headers: {}) + if consistencylevel + headers["consistencylevel"] = consistencylevel + end + response = get_raw(path, params, headers) parse_response(response) end - def post(path, body) - response = conn.post(path, body.to_json) + def post(path, body, headers: {}) + response = conn.post(path, body.to_json, headers) parse_response(response) end - def patch(path, body) - response = conn.patch(path, body.to_json) + def patch(path, body, headers: {}) + response = conn.patch(path, body.to_json, headers) parse_response(response) end @@ -133,10 +144,11 @@ def parse_response(response) class Client attr_reader :connection - def initialize(access_token:, faraday_adapter: Faraday.default_adapter) - @connection = FaradayConnection.new(access_token: access_token, faraday_adapter: faraday_adapter) + def initialize(access_token:, faraday_adapter: Faraday.default_adapter, version: 'v1.0') + @connection = FaradayConnection.new(access_token: access_token, faraday_adapter: faraday_adapter, version: version) end + # @return Users def users Users.new(client: connection) end @@ -145,16 +157,44 @@ def subscriptions Subscriptions.new(client: connection) end + # @return MsGraphRest::Mails def mails Mails.new(client: connection) end + # @return MsGraphRest::Photos def photos Photos.new(client: connection) end - def calendar_view(path = '/me/calendar/') - CalendarView.new(path, client: connection) + # @return MsGraphRest::CalendarView + def calendar_view + CalendarView.new(client: connection) + end + + # @return MsGraphRest::CalendarGetSchedule + def calendar_get_schedule + CalendarGetSchedule.new(client: connection) + end + + # @return MsGraphRest::CalendarCreateEvent + def calendar_create_event + CalendarCreateEvent.new(client: connection) + end + + # @return MsGraphRest::CalendarCreateEvent + def calendar_groups + CalendarGroups.new(client: connection) + end + + # @return MsGraphRest::CalendarCreateEvent + def calendars + Calendars.new(client: connection) + end + + # @return MsGraphRest::Places + def places + Places.new(client: connection) end def messages(path = 'me') diff --git a/lib/ms_graph_rest/calendar_create_event.rb b/lib/ms_graph_rest/calendar_create_event.rb new file mode 100644 index 0000000..7856f3c --- /dev/null +++ b/lib/ms_graph_rest/calendar_create_event.rb @@ -0,0 +1,70 @@ +require 'camel_snake_struct' +require_relative 'modifying_action' +require_relative 'response' + +module MsGraphRest + class CalendarCreateEvent < ModifyingAction + Response.example("value" => [], "@odata.context" => "", "@odata.nextLink" => "") + + # Issues getSchedule. If user_id is given, uses the + # /users/ID/calendar/getSchedule, otherwise me/calendar/getSchedule endpoint + # @return Response + # @param start_time [Time] From Date Time + # @param end_time [Time] To Date Time + # @param subject [String] + # @param body [String] + # @param content_type [String] HTML or TEXT + # @param user_id [String] Optional user id that is used for the request + # @param importance [String] normal low high + # @param all_day [Boolean] + # @param draft [Boolean] + # @param allow_new_time_proposals [Boolean] + # @param attendees [Array] + # @param location [Hash] + def create( + subject:, + body:, + start_time:, + end_time:, + location:, + attendees:, + allow_new_time_proposals:, + user_id: nil, + all_day: false, + draft: false, + sensitivity: 'normal', + importance: 'normal', + content_type: "HTML" + ) + start_time = start_time.iso8601 if start_time.respond_to?(:iso8601) + end_time = end_time.iso8601 if end_time.respond_to?(:iso8601) + + body = { + subject: subject, + body: { + content: body, + contentType: content_type, + }, + sensitivity: sensitivity, + importance: importance, + start: { + dateTime: start_time, + timeZone: 'UTC' + }, + location: location, + end: { + dateTime: end_time, + timeZone: 'UTC' + }, + isAllDay: all_day, + isDraft: draft, + allowNewTimeProposals: allow_new_time_proposals, + attendees: attendees, + }.compact + + path = user_id ? "users/#{CGI.escape(user_id)}/events" : "me/events" + + Response.new(client.post(path, body)) + end + end +end diff --git a/lib/ms_graph_rest/calendar_get_schedule.rb b/lib/ms_graph_rest/calendar_get_schedule.rb new file mode 100644 index 0000000..73572fc --- /dev/null +++ b/lib/ms_graph_rest/calendar_get_schedule.rb @@ -0,0 +1,42 @@ +require 'camel_snake_struct' +require_relative 'chainable_action' +require_relative 'response_with_pagination' + +module MsGraphRest + class CalendarGetSchedule < ChainableAction + class Response < ResponseWithPagination + end + Response.example("value" => [], "@odata.context" => "", "@odata.nextLink" => "") + + # Issues getSchedule. If user_id is given, uses the + # /users/ID/calendar/getSchedule, otherwise me/calendar/getSchedule endpoint + # @return Response + # @param start_time [Time] Min Date Time + # @param end_time [Time] Max Date Time + # @param schedules [Array] List of user mails to get schedules for + # @param availability_view_interval [Integer] + # @param user_id [String] Optional user id that is used for the request + def get(start_time:, end_time:, schedules:, availability_view_interval: nil, user_id: nil) + start_time = start_time.iso8601 if start_time.respond_to?(:iso8601) + end_time = end_time.iso8601 if end_time.respond_to?(:iso8601) + + path = user_id ? "users/#{CGI.escape(user_id)}/calendar/getSchedule" : "me/calendar/getSchedule" + + body = { + startTime: { + dateTime: start_time, + timeZone: 'UTC' + }, + endTime: { + dateTime: end_time, + timeZone: 'UTC' + }, + schedules: schedules, + availabilityViewInterval: availability_view_interval + }.compact + + Response.new(client.post(path + "?#{query.to_query}", body)) + end + end +end + diff --git a/lib/ms_graph_rest/calendar_groups.rb b/lib/ms_graph_rest/calendar_groups.rb new file mode 100644 index 0000000..aeb913d --- /dev/null +++ b/lib/ms_graph_rest/calendar_groups.rb @@ -0,0 +1,22 @@ +require 'camel_snake_struct' + +module MsGraphRest + class CalendarGroups < ChainableAction + class Response < ResponseWithPagination + end + Response.example('value' => [], "@odata.context" => "", "@odata.nextLink" => "") + + attr_reader :client, :path, :query + + def initialize(client:, query: {}) + @client = client + @query = query + end + + def get(user_id:) + path = user_id ? "users/#{user_id}/calendarGroups" : "me/calendarGroups" + Response.new(client.get(path, {})) + end + end +end + diff --git a/lib/ms_graph_rest/calendar_view.rb b/lib/ms_graph_rest/calendar_view.rb index d237f3c..bc94fe9 100644 --- a/lib/ms_graph_rest/calendar_view.rb +++ b/lib/ms_graph_rest/calendar_view.rb @@ -1,75 +1,27 @@ require 'camel_snake_struct' module MsGraphRest - class CalendarView - class Response < CamelSnakeStruct - include Enumerable - - def initialize(data) - @data = data - super(data) - end - - def each - value.each { |val| yield(val) } - end - - def next_get_query - return nil unless odata_next_link - - uri = URI.parse(odata_next_link) - params = CGI.parse(uri.query) - { start_date_time: params["startDateTime"]&.first, - end_date_time: params["endDateTime"]&.first, - skip: params["$skip"]&.first, - top: params["$top"]&.first, - select: params["$select"]&.first }.compact - end - - def size - value.size - end - - def to_h - to_hash - end + class CalendarView < ChainableAction + class Response < ResponseWithPagination end Response.example('value' => [], "@odata.context" => "", "@odata.nextLink" => "") attr_reader :client, :path, :query - def initialize(path, client:, query: {}) - @path = "#{path.to_str}".gsub('//', '/') - @path[0] = '' if @path.start_with?('/') + def initialize(client:, query: {}) @client = client @query = query end - def get(start_date_time:, end_date_time:, skip: nil, top: nil, select: nil) + def get(start_date_time:, end_date_time:, skip: nil, top: nil, select: nil, user_id: nil) start_date_time = start_date_time.iso8601 if start_date_time.respond_to?(:iso8601) end_date_time = end_date_time.iso8601 if end_date_time.respond_to?(:iso8601) + path = user_id ? "users/#{user_id}/calendar/calendarView" : "me/calendar" - Response.new(client.get("#{path}/calendarView", - query.merge({ 'startDateTime' => start_date_time, - 'endDateTime' => end_date_time, - '$skip' => skip, - '$top' => top, - '$select' => select }.compact))) - end - - def create(options) - Response.new(client.post("#{path}", options)) - end - - def select(val) - val = val.map(&:to_s).map { |v| v.camelize(:lower) }.join(',') if val.is_a?(Array) - new_with_query(query.merge('$select' => val)) - end - - private + query['startDateTime'] = start_date_time + query['endDateTime'] = end_date_time - def new_with_query(query) - self.class.new(path, client: client, query: query) + Response.new(client.get(path, query)) end end end diff --git a/lib/ms_graph_rest/calendars.rb b/lib/ms_graph_rest/calendars.rb new file mode 100644 index 0000000..949edc6 --- /dev/null +++ b/lib/ms_graph_rest/calendars.rb @@ -0,0 +1,28 @@ +require 'camel_snake_struct' + +module MsGraphRest + class Calendars < ChainableAction + class Response < ResponseWithPagination + end + Response.example('value' => [], "@odata.context" => "", "@odata.nextLink" => "") + + attr_reader :client, :path, :query + + def initialize(client:, query: {}) + @client = client + @query = query + end + + def get(user_id: nil, calendar_group: nil) + path = + case [user_id.nil?, calendar_group.nil?] + when [true, true] then "me/calendars" + when [false, true] then "users/#{user_id}/calendars" + when [true, false] then "me/calendarGroups/#{calendar_group}/calendars" + when [false, false] then "users/#{user_id}/calendarGroups/#{calendar_group}/calendars" + end + + Response.new(client.get(path, {})) + end + end +end diff --git a/lib/ms_graph_rest/chainable_action.rb b/lib/ms_graph_rest/chainable_action.rb new file mode 100644 index 0000000..e3a958d --- /dev/null +++ b/lib/ms_graph_rest/chainable_action.rb @@ -0,0 +1,73 @@ +module MsGraphRest + class ChainableAction + attr_reader :client, :query + def initialize(client:, query: {}) + @client = client + @query = query.with_indifferent_access + end + + def get() + raise NotImplementedError + end + + # Auto paginates until no odata_next_link is left any more. Use with caution + # Uses .get underhood + # @param **args + def all(**args) + out = nil + each_page(**args) do |response| + if out + out = out.merge_with_next_page(response) + else + out = response + end + end + out + end + + # Auto paginates until no odata_next_link is left any more. Use with caution + # Uses .get underhood + # @param **args + # @yield ResponseWithPagination + def each_page(**args, &block) + loop do + response = get(**args) + yield(response) + + break if response.odata_next_link.nil? + + parameters = Rack::Utils.parse_nested_query(URI(response.odata_next_link).query) + parameters.each do |key, value| + query[key] = value + end + end + end + + def select(val) + val = val.map(&:to_s).map { |v| v.camelize(:lower) }.join(',') if val.is_a?(Array) + new_with_query(query.merge("$select": val)) + end + + def top(val) + new_with_query(query.merge("$top": val)) + end + + def skip(val) + new_with_query(query.merge("$skip": val)) + end + + def skiptoken(val) + new_with_query(query.merge("$skiptoken": val)) + end + + def filter(val) + new_with_query(query.merge("$filter": val)) + end + + private + + def new_with_query(query) + self.class.new(client: client, query: query) + end + end +end diff --git a/lib/ms_graph_rest/find_rooms.rb b/lib/ms_graph_rest/find_rooms.rb new file mode 100644 index 0000000..4ff3b98 --- /dev/null +++ b/lib/ms_graph_rest/find_rooms.rb @@ -0,0 +1,21 @@ +require_relative 'chainable_action' +require_relative 'response_with_pagination' + +module MsGraphRest + class FindRooms < ChainableAction + class Response < ResponseWithPagination + end + Response.example('value' => [], "@odata.context" => "", "@odata.nextLink" => "") + + # @param tenant_id [String] Optional tenant_id, if not given, uses the /me path + # @param room_list [String] E-Mail address of the room list to filter on + def get(tenant_id: nil, room_list: nil) + path = tenant_id ? "users/#{CGI.escape(tenant_id)}/findRooms" : "me/findRooms" + if room_list + path += "(RoomList='#{CGI.escape(room_list)}')" + end + Response.new(client.get(path, query)) + end + end +end + diff --git a/lib/ms_graph_rest/modifying_action.rb b/lib/ms_graph_rest/modifying_action.rb new file mode 100644 index 0000000..694aebe --- /dev/null +++ b/lib/ms_graph_rest/modifying_action.rb @@ -0,0 +1,13 @@ +module MsGraphRest + class ModifyingAction + attr_reader :client, :query + def initialize(client:) + @client = client + end + + def create() + raise NotImplementedError + end + end +end + diff --git a/lib/ms_graph_rest/places.rb b/lib/ms_graph_rest/places.rb new file mode 100644 index 0000000..6db1a96 --- /dev/null +++ b/lib/ms_graph_rest/places.rb @@ -0,0 +1,17 @@ +require_relative 'chainable_action' +require_relative 'response_with_pagination' + +module MsGraphRest + class Places < ChainableAction + class Response < ResponseWithPagination + end + Response.example('value' => [], "@odata.context" => "", "@odata.nextLink" => "") + + # @param path [String] either microsoft.graph.room or microsoft.graph.roomlist + def get(path: 'microsoft.graph.room') + raise ArgumentError unless path.in?(['microsoft.graph.room', 'microsoft.graph.roomlist']) + + Response.new(client.get("places/#{path}", query)) + end + end +end diff --git a/lib/ms_graph_rest/response.rb b/lib/ms_graph_rest/response.rb new file mode 100644 index 0000000..6615015 --- /dev/null +++ b/lib/ms_graph_rest/response.rb @@ -0,0 +1,25 @@ +require 'camel_snake_struct' + +module MsGraphRest + class Response < CamelSnakeStruct + include Enumerable + + def initialize(data) + @data = data + super(data) + end + + def each + value.each { |val| yield(val) } + end + + def size + value.size + end + + def to_h + to_hash + end + end +end + diff --git a/lib/ms_graph_rest/response_with_pagination.rb b/lib/ms_graph_rest/response_with_pagination.rb new file mode 100644 index 0000000..f636945 --- /dev/null +++ b/lib/ms_graph_rest/response_with_pagination.rb @@ -0,0 +1,43 @@ +require 'camel_snake_struct' + +module MsGraphRest + class ResponseWithPagination < CamelSnakeStruct + include Enumerable + + def initialize(data) + @data = data + super(data) + end + + def each + value.each { |val| yield(val) } + end + + def next_get_query + return nil unless odata_next_link + + uri = URI.parse(odata_next_link) + params = CGI.parse(uri.query) + { + skip: params["$skip"]&.first, + skiptoken: params["$skiptoken"]&.first, + top: params["$top"]&.first, + select: params["$select"]&.first + }.compact + end + + def merge_with_next_page(response) + new_data = response.to_hash + new_data['value'] = to_hash['value'] + new_data['value'] + self.class.new(new_data) + end + + def size + value.size + end + + def to_h + to_hash + end + end +end diff --git a/lib/ms_graph_rest/users.rb b/lib/ms_graph_rest/users.rb index a0b4d70..b37f8f0 100644 --- a/lib/ms_graph_rest/users.rb +++ b/lib/ms_graph_rest/users.rb @@ -1,67 +1,18 @@ -require 'camel_snake_struct' +require_relative 'chainable_action' +require_relative 'response_with_pagination' module MsGraphRest - class Users - class Response < CamelSnakeStruct - include Enumerable - - def initialize(data) - @data = data - super(data) - end - - def each - value.each { |val| yield(val) } - end - - def next_get_query - return nil unless odata_next_link - - uri = URI.parse(odata_next_link) - params = CGI.parse(uri.query) - { select: params["$select"]&.first, - skiptoken: params["$skiptoken"]&.first, - filter: params["$filter"]&.first }.compact - end - - def size - value.size - end - - def [](key) - @data[key] - end + class Users < ChainableAction + class Response < ResponseWithPagination end Response.example('value' => [], "@odata.context" => "", "@odata.nextLink" => "") - attr_reader :client - attr_reader :query - - def initialize(client:, query: {}) - @client = client - @query = query + def get + Response.new(client.get("users", query)) end - def get(select: nil, filter: nil, skiptoken: nil) - Response.new(client.get("users", query.merge({ '$select' => select, - '$filter' => filter, - '$skiptoken' => skiptoken }.compact))) - end - - def filter(val) - new_with_query(query.merge('$filter' => val)) - end - - def select(val) - val = val.map(&:to_s).map { |v| v.camelize(:lower) }.join(',') if val.is_a?(Array) - new_with_query(query.merge('$select' => val)) - end - - private - - def new_with_query(query) - self.class.new(client: client, - query: query) + def count + client.get("users/$count", query, consistencylevel: "eventual") end end end From 1b5617b12f0838b89acbd29409884796cd9854a5 Mon Sep 17 00:00:00 2001 From: Stefan Wienert Date: Fri, 10 Sep 2021 09:24:21 +0200 Subject: [PATCH 2/9] Feat: Update/Cancel Event, Online Meetings --- lib/ms_graph_rest.rb | 26 +++++++- lib/ms_graph_rest/calendar_cancel_event.rb | 22 +++++++ lib/ms_graph_rest/calendar_create_event.rb | 3 + lib/ms_graph_rest/calendar_update_event.rb | 75 ++++++++++++++++++++++ lib/ms_graph_rest/calendar_view.rb | 2 +- lib/ms_graph_rest/online_meetings.rb | 53 +++++++++++++++ 6 files changed, 179 insertions(+), 2 deletions(-) create mode 100644 lib/ms_graph_rest/calendar_cancel_event.rb create mode 100644 lib/ms_graph_rest/calendar_update_event.rb create mode 100644 lib/ms_graph_rest/online_meetings.rb diff --git a/lib/ms_graph_rest.rb b/lib/ms_graph_rest.rb index c4755cf..d066135 100644 --- a/lib/ms_graph_rest.rb +++ b/lib/ms_graph_rest.rb @@ -4,10 +4,14 @@ require_relative 'ms_graph_rest/version' require_relative 'ms_graph_rest/calendar_create_event' +require_relative 'ms_graph_rest/calendar_update_event' +require_relative 'ms_graph_rest/calendar_cancel_event' require_relative 'ms_graph_rest/calendar_get_schedule' require_relative 'ms_graph_rest/calendar_groups' require_relative 'ms_graph_rest/calendar_view' require_relative 'ms_graph_rest/calendars' +require_relative 'ms_graph_rest/online_meetings' + require_relative 'ms_graph_rest/error' require_relative 'ms_graph_rest/find_rooms' require_relative 'ms_graph_rest/groups' @@ -135,7 +139,12 @@ def delete(path) private def parse_response(response) - MultiJson.load(response.body) + body = response.body + if body.empty? + true + else + MultiJson.load(response.body) + end rescue MultiJson::ParseError => e raise MsGraphRest::ParseError.new(e.message, response.body) end @@ -177,11 +186,26 @@ def calendar_get_schedule CalendarGetSchedule.new(client: connection) end + # @return MsGraphRest::OnlineMeetings + def online_meetings + OnlineMeetings.new(client: connection) + end + # @return MsGraphRest::CalendarCreateEvent def calendar_create_event CalendarCreateEvent.new(client: connection) end + # @return MsGraphRest::CalendarUpdateEvent + def calendar_update_event + CalendarUpdateEvent.new(client: connection) + end + + # @return MsGraphRest::CalendarCancelEvent + def calendar_cancel_event + CalendarCancelEvent.new(client: connection) + end + # @return MsGraphRest::CalendarCreateEvent def calendar_groups CalendarGroups.new(client: connection) diff --git a/lib/ms_graph_rest/calendar_cancel_event.rb b/lib/ms_graph_rest/calendar_cancel_event.rb new file mode 100644 index 0000000..7ee33e3 --- /dev/null +++ b/lib/ms_graph_rest/calendar_cancel_event.rb @@ -0,0 +1,22 @@ +module MsGraphRest + class CalendarCancelEvent < ModifyingAction + Response.example("value" => [], "@odata.context" => "", "@odata.nextLink" => "") + + # Issues getSchedule. If user_id is given, uses the + # /users/ID/calendar/getSchedule, otherwise me/calendar/getSchedule endpoint + # @return Response + # @param id [String] MSOffice Event ID + # @param user_id [String] Optional user id that is used for the request + def cancel(id:, user_id: nil, comment: nil) + # POST /me/events/{id}/cancel + # POST /users/{id | userPrincipalName}/events/{id}/cancel + + path = user_id ? "users/#{CGI.escape(user_id)}/events/#{id}/cancel" : "me/events/#{id}/cancel" + body = { comment: comment }.compact + + client.post(path, body) + end + end +end + + diff --git a/lib/ms_graph_rest/calendar_create_event.rb b/lib/ms_graph_rest/calendar_create_event.rb index 7856f3c..dd820cd 100644 --- a/lib/ms_graph_rest/calendar_create_event.rb +++ b/lib/ms_graph_rest/calendar_create_event.rb @@ -20,6 +20,7 @@ class CalendarCreateEvent < ModifyingAction # @param draft [Boolean] # @param allow_new_time_proposals [Boolean] # @param attendees [Array] + # @param show_as [String] busy, tentative # @param location [Hash] def create( subject:, @@ -32,6 +33,7 @@ def create( user_id: nil, all_day: false, draft: false, + show_as: 'busy', sensitivity: 'normal', importance: 'normal', content_type: "HTML" @@ -57,6 +59,7 @@ def create( timeZone: 'UTC' }, isAllDay: all_day, + showAs: show_as, isDraft: draft, allowNewTimeProposals: allow_new_time_proposals, attendees: attendees, diff --git a/lib/ms_graph_rest/calendar_update_event.rb b/lib/ms_graph_rest/calendar_update_event.rb new file mode 100644 index 0000000..84d8616 --- /dev/null +++ b/lib/ms_graph_rest/calendar_update_event.rb @@ -0,0 +1,75 @@ +require 'camel_snake_struct' +require_relative 'modifying_action' +require_relative 'response' + +module MsGraphRest + class CalendarUpdateEvent < ModifyingAction + Response.example("value" => [], "@odata.context" => "", "@odata.nextLink" => "") + + # Issues getSchedule. If user_id is given, uses the + # /users/ID/calendar/getSchedule, otherwise me/calendar/getSchedule endpoint + # @return Response + # @param id [String] MSOffice Event ID + # @param start_time [Time] From Date Time + # @param end_time [Time] To Date Time + # @param subject [String] + # @param body [String] + # @param content_type [String] HTML or TEXT + # @param user_id [String] Optional user id that is used for the request + # @param importance [String] normal low high + # @param all_day [Boolean] + # @param draft [Boolean] + # @param allow_new_time_proposals [Boolean] + # @param attendees [Array] + # @param location [Hash] + def create( + id:, + subject:, + body:, + start_time:, + end_time:, + location:, + attendees:, + allow_new_time_proposals:, + user_id: nil, + show_as: 'busy', + all_day: false, + draft: false, + sensitivity: 'normal', + importance: 'normal', + content_type: "HTML" + ) + start_time = start_time.iso8601 if start_time.respond_to?(:iso8601) + end_time = end_time.iso8601 if end_time.respond_to?(:iso8601) + + body = { + subject: subject, + body: { + content: body, + contentType: content_type, + }, + sensitivity: sensitivity, + importance: importance, + start: { + dateTime: start_time, + timeZone: 'UTC' + }, + location: location, + end: { + dateTime: end_time, + timeZone: 'UTC' + }, + isAllDay: all_day, + showAs: show_as, + isDraft: draft, + allowNewTimeProposals: allow_new_time_proposals, + attendees: attendees, + }.compact + + path = user_id ? "users/#{CGI.escape(user_id)}/events/#{id}" : "me/events/#{id}" + + Response.new(client.patch(path, body)) + end + end +end + diff --git a/lib/ms_graph_rest/calendar_view.rb b/lib/ms_graph_rest/calendar_view.rb index bc94fe9..b5c9c76 100644 --- a/lib/ms_graph_rest/calendar_view.rb +++ b/lib/ms_graph_rest/calendar_view.rb @@ -16,7 +16,7 @@ def initialize(client:, query: {}) def get(start_date_time:, end_date_time:, skip: nil, top: nil, select: nil, user_id: nil) start_date_time = start_date_time.iso8601 if start_date_time.respond_to?(:iso8601) end_date_time = end_date_time.iso8601 if end_date_time.respond_to?(:iso8601) - path = user_id ? "users/#{user_id}/calendar/calendarView" : "me/calendar" + path = user_id ? "users/#{user_id}/calendar/calendarView" : "me/calendar/calendarView" query['startDateTime'] = start_date_time query['endDateTime'] = end_date_time diff --git a/lib/ms_graph_rest/online_meetings.rb b/lib/ms_graph_rest/online_meetings.rb new file mode 100644 index 0000000..1bdf8dd --- /dev/null +++ b/lib/ms_graph_rest/online_meetings.rb @@ -0,0 +1,53 @@ +require_relative 'chainable_action' +require_relative 'response_with_pagination' + +module MsGraphRest + class OnlineMeetings < ChainableAction + class Response < ResponseWithPagination + end + Response.example('value' => [], "@odata.context" => "", "@odata.nextLink" => "") + + def create(subject:, start_date_time:, end_date_time:, accept_language: "en", participants: nil, user_id: nil) + start_date_time = start_date_time.iso8601 if start_date_time.respond_to?(:iso8601) + end_date_time = end_date_time.iso8601 if end_date_time.respond_to?(:iso8601) + + body = { + startDateTime: start_date_time, + endDateTime: end_date_time, + subject: subject, + participants: participants + } + path = user_id ? "users/#{CGI.escape(user_id)}/onlineMeetings" : "me/onlineMeetings" + headers = { + "Accept-Language" => accept_language + } + Response.new(client.post(path, body, headers: headers)) + end + + # https://docs.microsoft.com/en-us/graph/api/onlinemeeting-update + def update(id:, subject: nil, start_date_time: nil, end_date_time: nil, participants: nil, user_id: nil, accept_language: nil) + start_date_time = start_date_time.iso8601 if start_date_time.respond_to?(:iso8601) + end_date_time = end_date_time.iso8601 if end_date_time.respond_to?(:iso8601) + + body = { + startDateTime: start_date_time, + endDateTime: end_date_time, + subject: subject, + participants: participants + } + path = user_id ? "users/#{user_id}/onlineMeetings/#{id}" : "me/onlineMeetings/#{id}" + headers = { + "Accept-Language" => accept_language + }.compact + Response.new(client.patch(path, body, headers: headers)) + end + + def delete(id:, user_id: nil) + # /me/onlineMeetings/{meetingId} + # DELETE /users/{userId}/onlineMeetings/{meetingId} + path = user_id ? "users/#{user_id}/onlineMeetings/#{id}" : "me/onlineMeetings/#{id}" + + client.delete(path) + end + end +end From 18b0d912a35692e464f2da96df77cdff94d55a99 Mon Sep 17 00:00:00 2001 From: Stefan Wienert Date: Mon, 13 Sep 2021 11:05:05 +0200 Subject: [PATCH 3/9] Style: Rubocop Fixes; Disabled MethodLing + ParameterList Cops --- .rubocop.yml | 5 ++-- lib/ms_graph_rest.rb | 3 +- lib/ms_graph_rest/calendar_cancel_event.rb | 2 -- lib/ms_graph_rest/calendar_create_event.rb | 30 ++++++++++---------- lib/ms_graph_rest/calendar_get_schedule.rb | 1 - lib/ms_graph_rest/calendar_groups.rb | 3 +- lib/ms_graph_rest/calendar_update_event.rb | 33 +++++++++++----------- lib/ms_graph_rest/calendar_view.rb | 4 ++- lib/ms_graph_rest/calendars.rb | 2 ++ lib/ms_graph_rest/chainable_action.rb | 5 +++- lib/ms_graph_rest/find_rooms.rb | 1 - lib/ms_graph_rest/modifying_action.rb | 2 +- lib/ms_graph_rest/online_meetings.rb | 4 ++- lib/ms_graph_rest/response.rb | 1 - 14 files changed, 51 insertions(+), 45 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 8dc4d39..c296f1a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -20,13 +20,14 @@ RSpec/MultipleMemoizedHelpers: Max: 10 Metrics/MethodLength: - Max: 12 + Enabled: false Metrics/ParameterLists: - Max: 8 + Enabled: false Metrics/CyclomaticComplexity: Max: 9 Metrics/PerceivedComplexity: Max: 9 + diff --git a/lib/ms_graph_rest.rb b/lib/ms_graph_rest.rb index d066135..2a5752b 100644 --- a/lib/ms_graph_rest.rb +++ b/lib/ms_graph_rest.rb @@ -154,7 +154,8 @@ class Client attr_reader :connection def initialize(access_token:, faraday_adapter: Faraday.default_adapter, version: 'v1.0') - @connection = FaradayConnection.new(access_token: access_token, faraday_adapter: faraday_adapter, version: version) + @connection = FaradayConnection.new(access_token: access_token, faraday_adapter: faraday_adapter, + version: version) end # @return Users diff --git a/lib/ms_graph_rest/calendar_cancel_event.rb b/lib/ms_graph_rest/calendar_cancel_event.rb index 7ee33e3..249633e 100644 --- a/lib/ms_graph_rest/calendar_cancel_event.rb +++ b/lib/ms_graph_rest/calendar_cancel_event.rb @@ -18,5 +18,3 @@ def cancel(id:, user_id: nil, comment: nil) end end end - - diff --git a/lib/ms_graph_rest/calendar_create_event.rb b/lib/ms_graph_rest/calendar_create_event.rb index dd820cd..072f5eb 100644 --- a/lib/ms_graph_rest/calendar_create_event.rb +++ b/lib/ms_graph_rest/calendar_create_event.rb @@ -23,21 +23,21 @@ class CalendarCreateEvent < ModifyingAction # @param show_as [String] busy, tentative # @param location [Hash] def create( - subject:, - body:, - start_time:, - end_time:, - location:, - attendees:, - allow_new_time_proposals:, - user_id: nil, - all_day: false, - draft: false, - show_as: 'busy', - sensitivity: 'normal', - importance: 'normal', - content_type: "HTML" - ) + subject:, + body:, + start_time:, + end_time:, + location:, + attendees:, + allow_new_time_proposals:, + user_id: nil, + all_day: false, + draft: false, + show_as: 'busy', + sensitivity: 'normal', + importance: 'normal', + content_type: "HTML" + ) start_time = start_time.iso8601 if start_time.respond_to?(:iso8601) end_time = end_time.iso8601 if end_time.respond_to?(:iso8601) diff --git a/lib/ms_graph_rest/calendar_get_schedule.rb b/lib/ms_graph_rest/calendar_get_schedule.rb index 73572fc..8ee14c8 100644 --- a/lib/ms_graph_rest/calendar_get_schedule.rb +++ b/lib/ms_graph_rest/calendar_get_schedule.rb @@ -39,4 +39,3 @@ def get(start_time:, end_time:, schedules:, availability_view_interval: nil, use end end end - diff --git a/lib/ms_graph_rest/calendar_groups.rb b/lib/ms_graph_rest/calendar_groups.rb index aeb913d..d8ac3c6 100644 --- a/lib/ms_graph_rest/calendar_groups.rb +++ b/lib/ms_graph_rest/calendar_groups.rb @@ -8,10 +8,12 @@ class Response < ResponseWithPagination attr_reader :client, :path, :query + # rubocop:disable Lint/MissingSuper def initialize(client:, query: {}) @client = client @query = query end + # rubocop:enable Lint/MissingSuper def get(user_id:) path = user_id ? "users/#{user_id}/calendarGroups" : "me/calendarGroups" @@ -19,4 +21,3 @@ def get(user_id:) end end end - diff --git a/lib/ms_graph_rest/calendar_update_event.rb b/lib/ms_graph_rest/calendar_update_event.rb index 84d8616..ba43481 100644 --- a/lib/ms_graph_rest/calendar_update_event.rb +++ b/lib/ms_graph_rest/calendar_update_event.rb @@ -23,22 +23,22 @@ class CalendarUpdateEvent < ModifyingAction # @param attendees [Array] # @param location [Hash] def create( - id:, - subject:, - body:, - start_time:, - end_time:, - location:, - attendees:, - allow_new_time_proposals:, - user_id: nil, - show_as: 'busy', - all_day: false, - draft: false, - sensitivity: 'normal', - importance: 'normal', - content_type: "HTML" - ) + id:, + subject:, + body:, + start_time:, + end_time:, + location:, + attendees:, + allow_new_time_proposals:, + user_id: nil, + show_as: 'busy', + all_day: false, + draft: false, + sensitivity: 'normal', + importance: 'normal', + content_type: "HTML" + ) start_time = start_time.iso8601 if start_time.respond_to?(:iso8601) end_time = end_time.iso8601 if end_time.respond_to?(:iso8601) @@ -72,4 +72,3 @@ def create( end end end - diff --git a/lib/ms_graph_rest/calendar_view.rb b/lib/ms_graph_rest/calendar_view.rb index b5c9c76..7ec08dc 100644 --- a/lib/ms_graph_rest/calendar_view.rb +++ b/lib/ms_graph_rest/calendar_view.rb @@ -8,12 +8,14 @@ class Response < ResponseWithPagination attr_reader :client, :path, :query + # rubocop:disable Lint/MissingSuper def initialize(client:, query: {}) @client = client @query = query end + # rubocop:enable Lint/MissingSuper - def get(start_date_time:, end_date_time:, skip: nil, top: nil, select: nil, user_id: nil) + def get(start_date_time:, end_date_time:, user_id: nil) start_date_time = start_date_time.iso8601 if start_date_time.respond_to?(:iso8601) end_date_time = end_date_time.iso8601 if end_date_time.respond_to?(:iso8601) path = user_id ? "users/#{user_id}/calendar/calendarView" : "me/calendar/calendarView" diff --git a/lib/ms_graph_rest/calendars.rb b/lib/ms_graph_rest/calendars.rb index 949edc6..88f4624 100644 --- a/lib/ms_graph_rest/calendars.rb +++ b/lib/ms_graph_rest/calendars.rb @@ -8,10 +8,12 @@ class Response < ResponseWithPagination attr_reader :client, :path, :query + # rubocop:disable Lint/MissingSuper def initialize(client:, query: {}) @client = client @query = query end + # rubocop:enable Lint/MissingSuper def get(user_id: nil, calendar_group: nil) path = diff --git a/lib/ms_graph_rest/chainable_action.rb b/lib/ms_graph_rest/chainable_action.rb index e3a958d..beb641c 100644 --- a/lib/ms_graph_rest/chainable_action.rb +++ b/lib/ms_graph_rest/chainable_action.rb @@ -1,6 +1,9 @@ +require "active_support/core_ext/hash/indifferent_access" + module MsGraphRest class ChainableAction attr_reader :client, :query + def initialize(client:, query: {}) @client = client @query = query.with_indifferent_access @@ -29,7 +32,7 @@ def all(**args) # Uses .get underhood # @param **args # @yield ResponseWithPagination - def each_page(**args, &block) + def each_page(**args) loop do response = get(**args) yield(response) diff --git a/lib/ms_graph_rest/find_rooms.rb b/lib/ms_graph_rest/find_rooms.rb index 4ff3b98..1ebfc02 100644 --- a/lib/ms_graph_rest/find_rooms.rb +++ b/lib/ms_graph_rest/find_rooms.rb @@ -18,4 +18,3 @@ def get(tenant_id: nil, room_list: nil) end end end - diff --git a/lib/ms_graph_rest/modifying_action.rb b/lib/ms_graph_rest/modifying_action.rb index 694aebe..becce02 100644 --- a/lib/ms_graph_rest/modifying_action.rb +++ b/lib/ms_graph_rest/modifying_action.rb @@ -1,6 +1,7 @@ module MsGraphRest class ModifyingAction attr_reader :client, :query + def initialize(client:) @client = client end @@ -10,4 +11,3 @@ def create() end end end - diff --git a/lib/ms_graph_rest/online_meetings.rb b/lib/ms_graph_rest/online_meetings.rb index 1bdf8dd..2fc6f9c 100644 --- a/lib/ms_graph_rest/online_meetings.rb +++ b/lib/ms_graph_rest/online_meetings.rb @@ -25,7 +25,9 @@ def create(subject:, start_date_time:, end_date_time:, accept_language: "en", pa end # https://docs.microsoft.com/en-us/graph/api/onlinemeeting-update - def update(id:, subject: nil, start_date_time: nil, end_date_time: nil, participants: nil, user_id: nil, accept_language: nil) + def update( + id:, subject: nil, start_date_time: nil, end_date_time: nil, participants: nil, user_id: nil, accept_language: nil + ) start_date_time = start_date_time.iso8601 if start_date_time.respond_to?(:iso8601) end_date_time = end_date_time.iso8601 if end_date_time.respond_to?(:iso8601) diff --git a/lib/ms_graph_rest/response.rb b/lib/ms_graph_rest/response.rb index 6615015..a5a52c2 100644 --- a/lib/ms_graph_rest/response.rb +++ b/lib/ms_graph_rest/response.rb @@ -22,4 +22,3 @@ def to_h end end end - From 3e4a1796885716c2d4434fd9aef813fb50878f13 Mon Sep 17 00:00:00 2001 From: Stefan Wienert Date: Thu, 6 Oct 2022 14:58:50 +0200 Subject: [PATCH 4/9] Fix: relax gem dependencies for rails 7 --- ms_graph_rest.gemspec | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ms_graph_rest.gemspec b/ms_graph_rest.gemspec index 8f30fa5..0f142ba 100644 --- a/ms_graph_rest.gemspec +++ b/ms_graph_rest.gemspec @@ -24,9 +24,9 @@ Gem::Specification.new do |spec| spec.bindir = 'exe' spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] - spec.add_dependency 'activesupport', '>= 3.2', '< 7.0' - spec.add_dependency 'camel_snake_struct', '>= 0.1.0', '< 2.0' + spec.add_dependency 'activesupport', '>= 3.2', '< 8.0' + spec.add_dependency 'camel_snake_struct', '>= 0.1.0' spec.add_dependency 'faraday', '>= 0.10.0', '< 2.0' - spec.add_dependency 'hashie', '>= 3.1.0', '< 5.0' - spec.add_dependency 'multi_json', '>= 1.4.0', '< 2.0' + spec.add_dependency 'hashie', '>= 3.1.0' + spec.add_dependency 'multi_json', '>= 1.4.0' end From 8d999f92f7e44b143125e672529338212cda26ec Mon Sep 17 00:00:00 2001 From: Stefan Wienert Date: Thu, 13 Oct 2022 11:07:50 +0200 Subject: [PATCH 5/9] Feat: find_event --- lib/ms_graph_rest.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/ms_graph_rest.rb b/lib/ms_graph_rest.rb index 2a5752b..7c5bed6 100644 --- a/lib/ms_graph_rest.rb +++ b/lib/ms_graph_rest.rb @@ -10,6 +10,7 @@ require_relative 'ms_graph_rest/calendar_groups' require_relative 'ms_graph_rest/calendar_view' require_relative 'ms_graph_rest/calendars' +require_relative 'ms_graph_rest/find_event' require_relative 'ms_graph_rest/online_meetings' require_relative 'ms_graph_rest/error' @@ -177,6 +178,10 @@ def photos Photos.new(client: connection) end + def find_event + FindEvent.new(client: connection) + end + # @return MsGraphRest::CalendarView def calendar_view CalendarView.new(client: connection) From 8002a962bbdd69483a0aa11404b28c97675f6fc0 Mon Sep 17 00:00:00 2001 From: Stefan Wienert Date: Fri, 14 Oct 2022 08:20:56 +0200 Subject: [PATCH 6/9] Forgot.. --- lib/ms_graph_rest/find_event.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 lib/ms_graph_rest/find_event.rb diff --git a/lib/ms_graph_rest/find_event.rb b/lib/ms_graph_rest/find_event.rb new file mode 100644 index 0000000..ce9a1bc --- /dev/null +++ b/lib/ms_graph_rest/find_event.rb @@ -0,0 +1,10 @@ +module MsGraphRest + class FindEvent < ChainableAction + Response.example("value" => [], "@odata.context" => "", "@odata.nextLink" => "") + + def get(id:, user_id: nil) + path = user_id ? "users/#{CGI.escape(user_id)}/events/#{id}" : "me/events/#{id}" + Response.new(client.get(path, {})) + end + end +end From 0a0eed2b54e4293b15edfb127233e16cd7a6af24 Mon Sep 17 00:00:00 2001 From: Stefan Wienert Date: Mon, 10 Feb 2025 15:24:32 +0000 Subject: [PATCH 7/9] Feat: allow any online meeting parameter --- lib/ms_graph_rest/online_meetings.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/ms_graph_rest/online_meetings.rb b/lib/ms_graph_rest/online_meetings.rb index 2fc6f9c..097c5b2 100644 --- a/lib/ms_graph_rest/online_meetings.rb +++ b/lib/ms_graph_rest/online_meetings.rb @@ -7,7 +7,7 @@ class Response < ResponseWithPagination end Response.example('value' => [], "@odata.context" => "", "@odata.nextLink" => "") - def create(subject:, start_date_time:, end_date_time:, accept_language: "en", participants: nil, user_id: nil) + def create(subject:, start_date_time:, end_date_time:, accept_language: "en", participants: nil, user_id: nil, **args) start_date_time = start_date_time.iso8601 if start_date_time.respond_to?(:iso8601) end_date_time = end_date_time.iso8601 if end_date_time.respond_to?(:iso8601) @@ -16,7 +16,7 @@ def create(subject:, start_date_time:, end_date_time:, accept_language: "en", pa endDateTime: end_date_time, subject: subject, participants: participants - } + }.merge(args) path = user_id ? "users/#{CGI.escape(user_id)}/onlineMeetings" : "me/onlineMeetings" headers = { "Accept-Language" => accept_language @@ -26,7 +26,7 @@ def create(subject:, start_date_time:, end_date_time:, accept_language: "en", pa # https://docs.microsoft.com/en-us/graph/api/onlinemeeting-update def update( - id:, subject: nil, start_date_time: nil, end_date_time: nil, participants: nil, user_id: nil, accept_language: nil + id:, subject: nil, start_date_time: nil, end_date_time: nil, participants: nil, user_id: nil, accept_language: nil, **args ) start_date_time = start_date_time.iso8601 if start_date_time.respond_to?(:iso8601) end_date_time = end_date_time.iso8601 if end_date_time.respond_to?(:iso8601) @@ -36,7 +36,7 @@ def update( endDateTime: end_date_time, subject: subject, participants: participants - } + }.merge(args) path = user_id ? "users/#{user_id}/onlineMeetings/#{id}" : "me/onlineMeetings/#{id}" headers = { "Accept-Language" => accept_language From e23a45138dd66342708c2617f11e391c0d9e034d Mon Sep 17 00:00:00 2001 From: Stefan Wienert Date: Wed, 2 Apr 2025 07:48:03 +0000 Subject: [PATCH 8/9] Feat: add option to submit events with user/calendar style --- lib/ms_graph_rest/calendar_cancel_event.rb | 27 +++++++++++++++++++--- lib/ms_graph_rest/calendar_create_event.rb | 12 +++++++++- lib/ms_graph_rest/calendar_update_event.rb | 26 ++++++++++++++++++++- 3 files changed, 60 insertions(+), 5 deletions(-) diff --git a/lib/ms_graph_rest/calendar_cancel_event.rb b/lib/ms_graph_rest/calendar_cancel_event.rb index 249633e..e8cf274 100644 --- a/lib/ms_graph_rest/calendar_cancel_event.rb +++ b/lib/ms_graph_rest/calendar_cancel_event.rb @@ -7,11 +7,32 @@ class CalendarCancelEvent < ModifyingAction # @return Response # @param id [String] MSOffice Event ID # @param user_id [String] Optional user id that is used for the request - def cancel(id:, user_id: nil, comment: nil) + # @param comment [String] Optional comment + # @param calendar_id [String] Optional calendar id + def cancel(id:, user_id: nil, comment: nil, calendar_id: nil) # POST /me/events/{id}/cancel # POST /users/{id | userPrincipalName}/events/{id}/cancel - - path = user_id ? "users/#{CGI.escape(user_id)}/events/#{id}/cancel" : "me/events/#{id}/cancel" + # POST /groups/{id}/events/{id}/cancel + # + # POST /me/calendar/events/{id}/cancel + # POST /users/{id | userPrincipalName}/calendar/events/{id}/cancel + # POST /groups/{id}/calendar/events/{id}/cancel + # + # POST /me/calendars/{id}/events/{id}/cancel + # POST /users/{id | userPrincipalName}/calendars/{id}/events/{id}/cancel + # + # POST /me/calendarGroups/{id}/calendars/{id}/events/{id}/cancel + # POST /users/{id | userPrincipalName}/calendarGroups/{id}/calendars/{id}/events/{id}/cancel + path = case [user_id.present?, user_id.present?] + when [false, true] + "me/calendars/#{calendar_id}/events/#{id}/cancel" + when [true, false] + "users/#{user_id}/events/#{id}/cancel" + when [true, true] + "users/#{user_id}/calendars/#{calendar_id}/events/#{id}/cancel" + else + "me/events/#{id}/cancel" + end body = { comment: comment }.compact client.post(path, body) diff --git a/lib/ms_graph_rest/calendar_create_event.rb b/lib/ms_graph_rest/calendar_create_event.rb index 072f5eb..d573cd8 100644 --- a/lib/ms_graph_rest/calendar_create_event.rb +++ b/lib/ms_graph_rest/calendar_create_event.rb @@ -31,6 +31,7 @@ def create( attendees:, allow_new_time_proposals:, user_id: nil, + calendar_id: nil, all_day: false, draft: false, show_as: 'busy', @@ -65,7 +66,16 @@ def create( attendees: attendees, }.compact - path = user_id ? "users/#{CGI.escape(user_id)}/events" : "me/events" + path = case [user_id.present?, calendar_id.present?] + when [true, true] + "users/#{user_id}/calendars/#{calendar_id}/events" + when [false, true] + "me/calendars/#{calendar_id}/events" + when [true, false] + "users/#{user_id}/events" + else + "me/events" + end Response.new(client.post(path, body)) end diff --git a/lib/ms_graph_rest/calendar_update_event.rb b/lib/ms_graph_rest/calendar_update_event.rb index ba43481..242da48 100644 --- a/lib/ms_graph_rest/calendar_update_event.rb +++ b/lib/ms_graph_rest/calendar_update_event.rb @@ -32,6 +32,7 @@ def create( attendees:, allow_new_time_proposals:, user_id: nil, + calendar_id: nil, show_as: 'busy', all_day: false, draft: false, @@ -66,7 +67,30 @@ def create( attendees: attendees, }.compact - path = user_id ? "users/#{CGI.escape(user_id)}/events/#{id}" : "me/events/#{id}" + # PATCH /me/events/{id} + # PATCH /users/{id | userPrincipalName}/events/{id} + # PATCH /groups/{id}/events/{id} + # + # PATCH /me/calendar/events/{id} + # PATCH /users/{id | userPrincipalName}/calendar/events/{id} + # PATCH /groups/{id}/calendar/events/{id} + # + # PATCH /me/calendars/{id}/events/{id} + # PATCH /users/{id | userPrincipalName}/calendars/{id}/events/{id} + # + # PATCH /me/calendarGroups/{id}/calendars/{id}/events/{id} + # PATCH /users/{id | userPrincipalName}/calendarGroups/{id}/calendars/{id}/events/{id} + path = case [user_id.present?, calendar_id.present?] + when [true, true] + "users/#{user_id}/calendars/#{calendar_id}/events/#{id}" + when [false, true] + "me/calendars/#{calendar_id}/events/#{id}" + when [true, false] + "users/#{user_id}/events/#{id}" + else + "me/events/#{id}" + end + Response.new(client.patch(path, body)) end From 05e33097eaadb600ac6cd13b573efab5e6027da0 Mon Sep 17 00:00:00 2001 From: Stefan Wienert Date: Wed, 2 Apr 2025 08:16:23 +0000 Subject: [PATCH 9/9] Feat: get calendar --- lib/ms_graph_rest.rb | 5 +++++ lib/ms_graph_rest/calendar.rb | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 lib/ms_graph_rest/calendar.rb diff --git a/lib/ms_graph_rest.rb b/lib/ms_graph_rest.rb index 7c5bed6..0c3548f 100644 --- a/lib/ms_graph_rest.rb +++ b/lib/ms_graph_rest.rb @@ -10,6 +10,7 @@ require_relative 'ms_graph_rest/calendar_groups' require_relative 'ms_graph_rest/calendar_view' require_relative 'ms_graph_rest/calendars' +require_relative 'ms_graph_rest/calendar' require_relative 'ms_graph_rest/find_event' require_relative 'ms_graph_rest/online_meetings' @@ -222,6 +223,10 @@ def calendars Calendars.new(client: connection) end + def calendar + Calendar.new(client: connection) + end + # @return MsGraphRest::Places def places Places.new(client: connection) diff --git a/lib/ms_graph_rest/calendar.rb b/lib/ms_graph_rest/calendar.rb new file mode 100644 index 0000000..ddeb5d6 --- /dev/null +++ b/lib/ms_graph_rest/calendar.rb @@ -0,0 +1,31 @@ +require 'camel_snake_struct' + +module MsGraphRest + class Calendar < ChainableAction + class Response < ResponseWithPagination + end + Response.example('value' => nil, "@odata.context" => "", "@odata.nextLink" => "") + + attr_reader :client, :path, :query + + # rubocop:disable Lint/MissingSuper + def initialize(client:, query: {}) + @client = client + @query = query + end + # rubocop:enable Lint/MissingSuper + + def get(calendar_id:, user_id: nil, calendar_group: nil) + path = + case [user_id.nil?, calendar_group.nil?] + when [true, true] then "me/calendars/#{calendar_id}" + when [false, true] then "users/#{user_id}/calendars/#{calendar_id}" + when [true, false] then "me/calendarGroups/#{calendar_group}/calendars/#{calendar_id}" + when [false, false] then "users/#{user_id}/calendarGroups/#{calendar_group}/calendars/#{calendar_id}" + end + + Response.new(client.get(path, {})) + end + end +end +