class CalInvite::Event
Constants
- PROVIDER_ALIASES
-
Legacy provider symbols that still resolve;
:ics_contenthas produced the same output as:icssince IcsContent became a subclass of Ics.
Attributes
Public Class Methods
Source
# File lib/cal_invite/event.rb 112 def initialize(attributes = {}) 113 attributes = attributes.dup # never mutate the caller's hash 114 @show_attendees = attributes.delete(:show_attendees) || false 115 @timezone = attributes.delete(:timezone) || CalInvite.configuration&.timezone || 'UTC' 116 @multi_day_sessions = attributes.delete(:multi_day_sessions) || [] 117 @all_day = attributes.delete(:all_day) || false 118 @uid = attributes.delete(:uid) || generate_uid 119 @sequence = attributes.delete(:sequence) || 0 120 @busy = attributes.key?(:busy) ? attributes.delete(:busy) : true 121 @visibility = attributes.delete(:visibility) || :public 122 @allow_counter = attributes.key?(:allow_counter) ? attributes.delete(:allow_counter) : true 123 124 assign_attributes(attributes) 125 126 validate! 127 end
Initializes a new Event instance with the given attributes.
@param attributes [Hash] The attributes to initialize the event with @option attributes [String] :title The event title @option attributes [Time] :start_time The event start time. Optional with :multi_day_sessions (defaults to the earliest session start). @option attributes [Time] :end_time The event end time. Optional with :multi_day_sessions (defaults to the latest session end). @option attributes [String] :description The event description @option attributes [String] :location The event location @option attributes [String] :url The event URL @option attributes [Array<String>] :attendees The event attendees @option attributes [String] :timezone The event timezone. Defaults to CalInvite.configuration.timezone (āUTCā unless configured). @option attributes [Boolean] :show_attendees (false) Whether to show attendees @option attributes [String] :notes Additional notes @option attributes [Array<Hash>] :multi_day_sessions Multi-day session details @option attributes [Boolean] :all_day (false) Whether itās an all-day event @option attributes [String, Hash] :organizer The event organizer: an email string, or e.g. { name: āJane Doeā, email: ājane@example.comā } @option attributes [String] :uid A stable identifier for this event. If omitted, a random one is generated and memoized on this instance. To update or cancel a previously sent invite, you MUST pass the same :uid used originally ā mail/calendar clients match REQUEST/CANCEL messages to an existing event by UID, not by content. @option attributes [Integer] :sequence (0) RFC 5545 SEQUENCE number. Increment it yourself each time you re-send a REQUEST or a CANCEL for the same :uid. @option attributes [Array<Float>, Hash] :geo Location coordinates, e.g. [37.4595, -122.1418] or { lat:, lng: } @option attributes [Array<Integer>] :reminders Minutes-before-start values; one VALARM per entry @option attributes [Boolean] :busy (true) Whether this event shows as busy on free/busy lookups @option attributes [Symbol, String] :visibility (:public) :public, :private, or :confidential @option attributes [String] :rrule A raw RFC 5545 recurrence rule value, e.g. āFREQ=WEEKLY;COUNT=5ā @option attributes [String] :calendar_name Calendar-level display name (X-WR-CALNAME) @option attributes [Symbol, String] :importance :low, :normal, or :high @option attributes [Boolean] :allow_counter (true) false emits X-MICROSOFT-DISALLOW-COUNTER
@raise [ArgumentError] If required attributes are missing or invalid, or a key isnāt an Event attribute
Public Instance Methods
Source
# File lib/cal_invite/event.rb 72 def end_time 73 @end_time || multi_day_sessions&.map { |session| session[:end_time] }&.compact&.max 74 end
The event end. Without an explicit value, a multi-day event ends at its latest session end.
@return [Time, nil]
# File lib/cal_invite/event.rb 166 def generate_calendar_url(provider, method: :publish) 167 validate! 168 provider_class_for(provider).new(self, method: method).generate 169 end
Generates a calendar URL (or, for the ics/ical/ics_content providers, raw iCalendar content) for the specified provider.
@param provider [Symbol, String] One of {CalInvite::Providers::SUPPORTED_PROVIDERS} (:ics_content is also accepted as a legacy alias of :ics) @param method [Symbol] The iCalendar METHOD to use (:publish, :request, :cancel, :reply, :counter, or :decline_counter). Only honored by the ics-family providers (ics, ical, ics_content); ignored by URL-based providers. - :request (with an {#organizer} set) produces an invite that mail clients (Gmail, Outlook, Apple Mail) recognize and render with Accept/Decline actions rather than as a plain attachment. - :cancel produces a cancellation (STATUS:CANCELLED) for a previously sent :request. Reuse the same {#uid} and bump {#sequence} so clients match it to the original invite instead of creating a new event. - :reply carries an attendeeās own PARTSTAT back to the organizer. - :counter carries an attendeeās proposed new {#start_time}/{#end_time} back to the organizer, keeping the original {#uid}/{#sequence}. Client support for rendering this as an actionable UI is inconsistent ā see CONFIGURATION.mdās āAttendee-proposed reschedules (COUNTER)ā. - :decline_counter is the organizer rejecting a :counter proposal. @return [String] The generated calendar URL or content @raise [ArgumentError] If required event attributes are missing or the provider is unsupported
@example Generate a Google Calendar URL event.generate_calendar_url(:google)
@example Generate an Outlook Calendar URL event.generate_calendar_url(:outlook)
@example Generate an RFC 5545 meeting request for emailing as an invite event.organizer = { name: āJane Doeā, email: ājane@example.comā } event.generate_calendar_url(:ics, method: :request)
@example Cancel a previously sent invite event.uid = āthe-original-uid@cal-inviteā # must match the original REQUEST event.sequence = 1 # incremented from the original event.generate_calendar_url(:ics, method: :cancel)
Source
# File lib/cal_invite/event.rb 64 def start_time 65 @start_time || multi_day_sessions&.map { |session| session[:start_time] }&.compact&.min 66 end
The event start. Without an explicit value, a multi-day event spans from its earliest session start, so single-event URL providers (Google, Outlook, Office 365) show the overall range.
@return [Time, nil]
# File lib/cal_invite/event.rb 182 def update_attributes(new_attributes) 183 assign_attributes(new_attributes) 184 validate! 185 end
Updates the event attributes with new values.
@param new_attributes [Hash] The new attributes to update @return [void] @raise [ArgumentError] If a key isnāt an Event attribute (nothing is changed), or the updated attributes make the event invalid
@example Update event title and time event.update_attributes( title: āUpdated Meetingā, start_time: Time.now + 3600 )
Private Instance Methods
# File lib/cal_invite/event.rb 259 def assign_attributes(attributes) 260 unknown = attributes.keys.reject { |key| respond_to?("#{key}=") } 261 raise ArgumentError, "Unknown attribute(s): #{unknown.join(', ')}" if unknown.any? 262 263 attributes.each { |key, value| send("#{key}=", value) } 264 end
Assigns attributes through their setters. Checks every key first, so an unknown key (e.g. a typo like locaton:) raises before anything changes instead of being silently dropped.
@param attributes [Hash] Attribute names (symbols or strings) to values @raise [ArgumentError] If any key isnāt an Event attribute @return [void]
Source
# File lib/cal_invite/event.rb 224 def capitalize_provider(string) 225 string.split('_').map(&:capitalize).join 226 end
Capitalizes each part of the provider name.
@param string [String] The provider name to capitalize @return [String] The capitalized provider name @example capitalize_provider(āgoogle_calendarā) # => āGoogleCalendarā
Source
# File lib/cal_invite/event.rb 193 def generate_uid 194 "#{Time.now.to_i}-#{SecureRandom.hex(8)}@cal-invite" 195 end
Generates a stable unique identifier for this event. Format: timestamp-randomhex@cal-invite
@return [String] The generated UID
# File lib/cal_invite/event.rb 207 def provider_class_for(provider) 208 key = provider.to_s.to_sym 209 key = PROVIDER_ALIASES.fetch(key, key) 210 unless CalInvite::Providers::SUPPORTED_PROVIDERS.include?(key) 211 raise ArgumentError, 212 "Unsupported provider #{provider.inspect}; supported: #{CalInvite::Providers::SUPPORTED_PROVIDERS.join(', ')}" 213 end 214 215 CalInvite::Providers.const_get(capitalize_provider(key.to_s), false) 216 end
Resolves a provider symbol to its class, accepting only {CalInvite::Providers::SUPPORTED_PROVIDERS} (plus {PROVIDER_ALIASES}).
@param provider [Symbol, String] The provider name @return [Class] The provider class @raise [ArgumentError] If the provider isnāt supported
Source
# File lib/cal_invite/event.rb 231 def validate! 232 raise ArgumentError, "Title is required" if title.nil? || title.strip.empty? 233 234 unless all_day 235 raise ArgumentError, "Start time is required for non-all-day events" if start_time.nil? 236 raise ArgumentError, "End time is required for non-all-day events" if end_time.nil? 237 end 238 239 validate_time_order!(start_time, end_time, "End time") 240 multi_day_sessions.each_with_index do |session, index| 241 label = "Session #{index + 1}" 242 raise ArgumentError, "#{label} requires start_time and end_time" unless session[:start_time] && session[:end_time] 243 244 validate_time_order!(session[:start_time], session[:end_time], "#{label} end_time") 245 end 246 247 unless CalInvite::IcalTimezone.valid?(timezone) 248 raise ArgumentError, "Unknown timezone #{timezone.inspect}: use 'UTC' or an IANA identifier such as 'America/New_York'" 249 end 250 end
Validates the event attributes.
@raise [ArgumentError] If required attributes are missing or invalid
# File lib/cal_invite/event.rb 273 def validate_time_order!(start_at, end_at, label) 274 return unless start_at && end_at 275 return if end_at > start_at || (all_day && end_at == start_at) 276 277 raise ArgumentError, "#{label} must be after start time" 278 end
Raises unless the end comes after the start. RFC 5545 requires DTEND to be later than DTSTART; all-day events may start and end on the same date.
@param start_at [Time, Date, nil] The start @param end_at [Time, Date, nil] The end @param label [String] What to call the end in the error message @raise [ArgumentError] If the end is before (or, for timed events, equal to) the start