diff --git a/CHANGELOG.md b/CHANGELOG.md index 22f99b92..7103c076 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ### Unreleased +* Add support for Event Conferencing * Fix update draft failing if version is not explicitly set * Fix draft `.send` logic diff --git a/lib/nylas.rb b/lib/nylas.rb index 8bb8e5b4..55d74871 100644 --- a/lib/nylas.rb +++ b/lib/nylas.rb @@ -53,6 +53,9 @@ require_relative "nylas/when" require_relative "nylas/free_busy" require_relative "nylas/time_slot" +require_relative "nylas/event_conferencing" +require_relative "nylas/event_conferencing_details" +require_relative "nylas/event_conferencing_autocreate" # Custom collection types require_relative "nylas/search_collection" @@ -123,6 +126,9 @@ module Nylas Types.registry[:contact_group] = Types::ModelType.new(model: ContactGroup) Types.registry[:when] = Types::ModelType.new(model: When) Types.registry[:time_slot] = Types::ModelType.new(model: TimeSlot) + Types.registry[:event_conferencing] = Types::ModelType.new(model: EventConferencing) + Types.registry[:event_conferencing_details] = Types::ModelType.new(model: EventConferencingDetails) + Types.registry[:event_conferencing_autocreate] = Types::ModelType.new(model: EventConferencingAutocreate) Types.registry[:neural] = Types::ModelType.new(model: Neural) Types.registry[:categorize] = Types::ModelType.new(model: Categorize) Types.registry[:neural_signature_contact] = Types::ModelType.new(model: NeuralSignatureContact) diff --git a/lib/nylas/event.rb b/lib/nylas/event.rb index 16832a47..03dcc87a 100644 --- a/lib/nylas/event.rb +++ b/lib/nylas/event.rb @@ -28,6 +28,7 @@ class Event attribute :title, :string attribute :when, :when attribute :metadata, :hash + attribute :conferencing, :event_conferencing attribute :original_start_time, :unix_timestamp attr_accessor :notify_participants @@ -40,6 +41,17 @@ def read_only? read_only end + def save + if conferencing + body = to_h + if body.dig(:conferencing, :details) && body.dig(:conferencing, :autocreate) + raise ArgumentError, "Cannot set both 'details' and 'autocreate' in conferencing object." + end + end + + super + end + def rsvp(status, notify_participants:) rsvp = Rsvp.new(api: api, status: status, notify_participants: notify_participants, event_id: id, account_id: account_id) diff --git a/lib/nylas/event_conferencing.rb b/lib/nylas/event_conferencing.rb new file mode 100644 index 00000000..5d26f748 --- /dev/null +++ b/lib/nylas/event_conferencing.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Nylas + # Structure to represent the Event Conferencing object + # @see https://developer.nylas.com/docs/connectivity/calendar/conference-sync-beta + class EventConferencing + include Model::Attributable + attribute :provider, :string + attribute :details, :event_conferencing_details + attribute :autocreate, :event_conferencing_autocreate + end +end diff --git a/lib/nylas/event_conferencing_autocreate.rb b/lib/nylas/event_conferencing_autocreate.rb new file mode 100644 index 00000000..ef206b7b --- /dev/null +++ b/lib/nylas/event_conferencing_autocreate.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +module Nylas + # Structure to represent the autocreate object within the Event Conferencing object + # @see https://developer.nylas.com/docs/connectivity/calendar/conference-sync-beta + class EventConferencingAutocreate + include Model::Attributable + attribute :settings, :hash, default: {} + end +end diff --git a/lib/nylas/event_conferencing_details.rb b/lib/nylas/event_conferencing_details.rb new file mode 100644 index 00000000..bfd4601a --- /dev/null +++ b/lib/nylas/event_conferencing_details.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +module Nylas + # Structure to represent the details object within the Event Conferencing object + # @see https://developer.nylas.com/docs/connectivity/calendar/conference-sync-beta + class EventConferencingDetails + include Model::Attributable + attribute :meeting_code, :string + attribute :password, :string + attribute :pin, :string + attribute :url, :string + has_n_of_attribute :phone, :string + end +end diff --git a/lib/nylas/model/attributable.rb b/lib/nylas/model/attributable.rb index 4fe5b78d..5dfd0d77 100644 --- a/lib/nylas/model/attributable.rb +++ b/lib/nylas/model/attributable.rb @@ -25,6 +25,8 @@ def to_h def assign(**data) data.each do |attribute_name, value| + next if value.nil? + if respond_to?(:"#{attribute_name}=") send(:"#{attribute_name}=", value) end diff --git a/lib/nylas/model/attributes.rb b/lib/nylas/model/attributes.rb index a270eb89..34a431d7 100644 --- a/lib/nylas/model/attributes.rb +++ b/lib/nylas/model/attributes.rb @@ -31,7 +31,9 @@ def merge(new_data) def to_h(keys: attribute_definitions.keys) keys.each_with_object({}) do |key, casted_data| value = attribute_definitions[key].serialize(self[key]) - casted_data[key] = value unless value.nil? || (value.respond_to?(:empty?) && value.empty?) + # If the value is an empty hash but we specify that it is valid (via default value), serialize it + casted_data[key] = value unless value.nil? || (value.respond_to?(:empty?) && value.empty? && + !(attribute_definitions[key].default == value && value.is_a?(Hash))) end end diff --git a/spec/nylas/event_spec.rb b/spec/nylas/event_spec.rb index 2406fd9c..65729384 100644 --- a/spec/nylas/event_spec.rb +++ b/spec/nylas/event_spec.rb @@ -37,6 +37,17 @@ }, metadata: { "event_type": "gathering" + }, + conferencing: { + provider: "Zoom Meeting", + details: { + url: "https://us02web.zoom.us/j/****************", + meeting_code: "213", + password: "xyz", + phone: [ + "+11234567890" + ] + } } } @@ -69,6 +80,11 @@ expect(event.when).to cover(Time.at(1_511_306_400)) expect(event.when).not_to cover(Time.at(1_511_306_401)) expect(event.metadata[:event_type]).to eql "gathering" + expect(event.conferencing.provider).to eql "Zoom Meeting" + expect(event.conferencing.details.url).to eql "https://us02web.zoom.us/j/****************" + expect(event.conferencing.details.meeting_code).to eql "213" + expect(event.conferencing.details.password).to eql "xyz" + expect(event.conferencing.details.phone).to eql ["+11234567890"] end end @@ -230,6 +246,109 @@ query: {} ) end + + it "sends the conferencing autocreate object even if settings is empty" do + api = instance_double(Nylas::API) + allow(api).to receive(:execute).and_return({}) + data = { + id: "event-id", + calendar_id: "cal-0987", + conferencing: { + provider: "Zoom meetings", + autocreate: { + settings: {} + } + } + } + event = described_class.from_json(JSON.dump(data), api: api) + + event.save + + expect(api).to have_received(:execute).with( + method: :put, + path: "/events/event-id", + payload: { + calendar_id: "cal-0987", + conferencing: { + provider: "Zoom meetings", + autocreate: { + settings: {} + } + } + }.to_json, + query: {} + ) + end + + it "sends the conferencing object if details alone is set" do + api = instance_double(Nylas::API) + allow(api).to receive(:execute).and_return({}) + data = { + id: "event-id", + calendar_id: "cal-0987", + conferencing: { + provider: "Zoom meetings", + details: { + url: "https://us02web.zoom.us/j/****************", + meeting_code: "213", + password: "xyz", + phone: [ + "+11234567890" + ] + } + } + } + event = described_class.from_json(JSON.dump(data), api: api) + + event.save + + expect(api).to have_received(:execute).with( + method: :put, + path: "/events/event-id", + payload: { + calendar_id: "cal-0987", + conferencing: { + provider: "Zoom meetings", + details: { + meeting_code: "213", + password: "xyz", + url: "https://us02web.zoom.us/j/****************", + phone: [ + "+11234567890" + ] + } + } + }.to_json, + query: {} + ) + end + + it "throws an error if both conferencing details and autocreate are set" do + api = instance_double(Nylas::API) + allow(api).to receive(:execute).and_return({}) + data = { + id: "event-id", + calendar_id: "cal-0987", + conferencing: { + provider: "Zoom meetings", + details: { + url: "https://us02web.zoom.us/j/****************", + meeting_code: "213", + password: "xyz", + phone: [ + "+11234567890" + ] + }, + autocreate: { + settings: {} + } + } + } + event = described_class.from_json(JSON.dump(data), api: api) + error = "Cannot set both 'details' and 'autocreate' in conferencing object." + + expect { event.save }.to raise_error(ArgumentError, error) + end end end