diff --git a/src/main/kotlin/com/nylas/NylasClient.kt b/src/main/kotlin/com/nylas/NylasClient.kt index 1a3e0d72..ce770e9e 100644 --- a/src/main/kotlin/com/nylas/NylasClient.kt +++ b/src/main/kotlin/com/nylas/NylasClient.kt @@ -151,6 +151,12 @@ open class NylasClient( */ open fun contacts(): Contacts = Contacts(this) + /** + * Access the Scheduler API + * @return The Scheduler API + */ + fun scheduler(): Scheduler = Scheduler(this) + /** * Get a URL builder instance for the Nylas API. */ diff --git a/src/main/kotlin/com/nylas/models/AvailabilityMethod.kt b/src/main/kotlin/com/nylas/models/AvailabilityMethod.kt index f0283a0c..82b17e51 100644 --- a/src/main/kotlin/com/nylas/models/AvailabilityMethod.kt +++ b/src/main/kotlin/com/nylas/models/AvailabilityMethod.kt @@ -11,4 +11,7 @@ enum class AvailabilityMethod { @Json(name = "max-availability") MAX_AVAILABILITY, + + @Json(name = "collective") + COLLECTIVE, } diff --git a/src/main/kotlin/com/nylas/models/AvailabilityRules.kt b/src/main/kotlin/com/nylas/models/AvailabilityRules.kt index 4b3919d1..1f4b2c66 100644 --- a/src/main/kotlin/com/nylas/models/AvailabilityRules.kt +++ b/src/main/kotlin/com/nylas/models/AvailabilityRules.kt @@ -14,7 +14,7 @@ data class AvailabilityRules( /** * The buffer to add to the start and end of a meeting. */ - @Json(name = "meeting_buffer") + @Json(name = "buffer") val buffer: MeetingBuffer? = null, /** * A default set of open hours to apply to all participants. @@ -27,8 +27,8 @@ data class AvailabilityRules( * The ID on events that Nylas considers when calculating the order of round-robin participants. * This is used for both max-fairness and max-availability methods. */ - @Json(name = "round_robin_event_id") - val roundRobinEventId: String? = null, + @Json(name = "round_robin_group_id") + val roundRobinGroupId: String? = null, ) { /** * A builder for creating a [AvailabilityRules]. @@ -37,7 +37,7 @@ data class AvailabilityRules( private var availabilityMethod: AvailabilityMethod? = null private var buffer: MeetingBuffer? = null private var defaultOpenHours: List<OpenHours>? = null - private var roundRobinEventId: String? = null + private var roundRobinGroupId: String? = null /** * Set the method used to determine availability for a meeting. @@ -65,10 +65,10 @@ data class AvailabilityRules( /** * Set the ID on events that Nylas considers when calculating the order of round-robin participants. * This is used for both max-fairness and max-availability methods. - * @param roundRobinEventId The ID on events that Nylas considers when calculating the order of round-robin participants. + * @param roundRobinGroupId The ID on events that Nylas considers when calculating the order of round-robin participants. * @return The builder. */ - fun roundRobinEventId(roundRobinEventId: String) = apply { this.roundRobinEventId = roundRobinEventId } + fun roundRobinGroupId(roundRobinGroupId: String) = apply { this.roundRobinGroupId = roundRobinGroupId } /** * Build the [AvailabilityRules] object. @@ -78,7 +78,7 @@ data class AvailabilityRules( availabilityMethod = availabilityMethod, buffer = buffer, defaultOpenHours = defaultOpenHours, - roundRobinEventId = roundRobinEventId, + roundRobinGroupId = roundRobinGroupId, ) } } diff --git a/src/main/kotlin/com/nylas/models/BookingGuest.kt b/src/main/kotlin/com/nylas/models/BookingGuest.kt new file mode 100644 index 00000000..5502a298 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/BookingGuest.kt @@ -0,0 +1,19 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a booking guest. + */ +data class BookingGuest( + /** + * The email address of the guest. + */ + @Json(name = "email") + val email: String, + /** + * The name of the guest. + */ + @Json(name = "name") + val name: String? = null, +) diff --git a/src/main/kotlin/com/nylas/models/BookingOrganizer.kt b/src/main/kotlin/com/nylas/models/BookingOrganizer.kt new file mode 100644 index 00000000..4568aff5 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/BookingOrganizer.kt @@ -0,0 +1,19 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a booking organizer. + */ +data class BookingOrganizer( + /** + * The email address of the participant designated as the organizer of the event. + */ + @Json(name = "email") + val email: String, + /** + * The name of the participant designated as the organizer of the event. + */ + @Json(name = "name") + val name: String? = null, +) diff --git a/src/main/kotlin/com/nylas/models/BookingReminder.kt b/src/main/kotlin/com/nylas/models/BookingReminder.kt new file mode 100644 index 00000000..842a16d4 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/BookingReminder.kt @@ -0,0 +1,29 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a booking reminder. + */ +data class BookingReminder( + /** + * The reminder type. + */ + @Json(name = "type") + val type: String, + /** + * The number of minutes before the event to send the reminder. + */ + @Json(name = "minutes_before_event") + val minutesBeforeEvent: Int, + /** + * The recipient of the reminder. + */ + @Json(name = "recipient") + val recipient: String? = null, + /** + * The subject of the email reminder. + */ + @Json(name = "email_subject") + val emailSubject: String? = null, +) diff --git a/src/main/kotlin/com/nylas/models/BookingStatus.kt b/src/main/kotlin/com/nylas/models/BookingStatus.kt new file mode 100644 index 00000000..c140c163 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/BookingStatus.kt @@ -0,0 +1,17 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Enum for booking statuses. + */ +enum class BookingStatus { + @Json(name = "pending") + PENDING, + + @Json(name = "booked") + BOOKED, + + @Json(name = "cancelled") + CANCELLED, +} diff --git a/src/main/kotlin/com/nylas/models/BookingType.kt b/src/main/kotlin/com/nylas/models/BookingType.kt new file mode 100644 index 00000000..4a40ef4f --- /dev/null +++ b/src/main/kotlin/com/nylas/models/BookingType.kt @@ -0,0 +1,14 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Enum for booking types. + */ +enum class BookingType { + @Json(name = "booking") + BOOKING, + + @Json(name = "organizer-confirmation") + ORGANIZER_CONFIRMATION, +} diff --git a/src/main/kotlin/com/nylas/models/ConfigurationAvailability.kt b/src/main/kotlin/com/nylas/models/ConfigurationAvailability.kt new file mode 100644 index 00000000..9c4d202e --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ConfigurationAvailability.kt @@ -0,0 +1,75 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of availability settings. + */ +data class ConfigurationAvailability( + /** + * The total number of minutes the event should last. + */ + @Json(name = "duration_minutes") + val durationMinutes: Int? = null, + /** + * The interval between meetings in minutes. + */ + @Json(name = "interval_minutes") + val intervalMinutes: Int? = null, + /** + * Nylas rounds each time slot to the nearest multiple of this number of minutes. + */ + @Json(name = "round_to") + val roundTo: Int? = null, + /** + * Availability rules for scheduling configuration. + */ + @Json(name = "availability_rules") + val availabilityRules: AvailabilityRules? = null, +) { + class Builder { + private var durationMinutes: Int? = null + private var intervalMinutes: Int? = null + private var roundTo: Int? = null + private var availabilityRules: AvailabilityRules? = null + + /** + * Set the duration of the event in minutes. + * @param durationMinutes The duration of the event in minutes. + * @return The builder. + */ + fun durationMinutes(durationMinutes: Int?) = apply { this.durationMinutes = durationMinutes } + + /** + * Set the interval between meetings in minutes. + * @param intervalMinutes The interval between meetings in minutes. + * @return The builder. + */ + fun intervalMinutes(intervalMinutes: Int?) = apply { this.intervalMinutes = intervalMinutes } + + /** + * Set Nylas rounds each time slot to the nearest multiple of this number of minutes. + * @param roundTo Nylas rounds each time slot to the nearest multiple of this number of minutes. + * @return The builder. + */ + fun roundTo(roundTo: Int?) = apply { this.roundTo = roundTo } + + /** + * Set availability rules for scheduling configuration. + * @param availabilityRules Availability rules for scheduling configuration. + * @return The builder. + */ + fun availabilityRules(availabilityRules: AvailabilityRules?) = apply { this.availabilityRules = availabilityRules } + + /** + * Build the [ConfigurationAvailability]. + * @return The [ConfigurationAvailability]. + */ + fun build() = ConfigurationAvailability( + durationMinutes, + intervalMinutes, + roundTo, + availabilityRules, + ) + } +} diff --git a/src/main/kotlin/com/nylas/models/ConfigurationAvailabilityParticipant.kt b/src/main/kotlin/com/nylas/models/ConfigurationAvailabilityParticipant.kt new file mode 100644 index 00000000..b2297da6 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ConfigurationAvailabilityParticipant.kt @@ -0,0 +1,52 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a participant in a booking. + */ + +data class ConfigurationAvailabilityParticipant( + /** + * @param calendarIds The calendar IDs that the event is created in. + */ + @Json(name = "calendar_ids") + val calendarIds: List<String>? = emptyList(), + /** + * Open hours for this participant. The endpoint searches for free time slots during these open hours. + */ + @Json(name = "open_hours") + val openHours: List<OpenHours>? = null, +) { + /** + * Builder for [ConfigurationAvailabilityParticipant]. + */ + class Builder { + private var calendarIds: List<String>? = null + private var openHours: List<OpenHours>? = null + + /** + * Set the calendar IDs for this participant. + * @param calendarIds Calendar IDs for this participant. + * @return The builder. + */ + fun calendarIds(calendarIds: List<String>) = apply { this.calendarIds = calendarIds } + + /** + * Set the open hours for this participant. + * @param openHours Open hours for this participant. + * @return The builder. + */ + fun openHours(openHours: List<OpenHours>) = apply { this.openHours = openHours } + + /** + * Set the open hours for this participant. + * @param openHours Open hours for this participant. + * @return The builder. + */ + fun build() = ConfigurationAvailabilityParticipant( + calendarIds, + openHours, + ) + } +} diff --git a/src/main/kotlin/com/nylas/models/ConfigurationBookingParticipant.kt b/src/main/kotlin/com/nylas/models/ConfigurationBookingParticipant.kt new file mode 100644 index 00000000..5946a2cc --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ConfigurationBookingParticipant.kt @@ -0,0 +1,34 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a participant in a booking. + */ +data class ConfigurationBookingParticipant( + /** + * The calendar ID that the event is created in. + */ + @Json(name = "calendar_id") + val calendarId: String? = null, +) { + /** + * Builder for [ConfigurationBookingParticipant]. + */ + class Builder { + private var calendarId: String? = null + + /** + * Set the calendar ID for this participant. + * @param calendarId The calendar ID for this participant. + * @return The builder. + */ + fun calendarId(calendarId: String?) = apply { this.calendarId = calendarId } + + /** + * Builds a [ConfigurationBookingParticipant] instance. + * @return The [ConfigurationBookingParticipant] instance. + */ + fun build() = ConfigurationBookingParticipant(calendarId) + } +} diff --git a/src/main/kotlin/com/nylas/models/ConfigurationEventBooking.kt b/src/main/kotlin/com/nylas/models/ConfigurationEventBooking.kt new file mode 100644 index 00000000..4acec054 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ConfigurationEventBooking.kt @@ -0,0 +1,148 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of an event booking. + */ +data class ConfigurationEventBooking( + /** + * The title of the event. + */ + @Json(name = "title") + val title: String? = null, + /** + * The description of the event. + */ + @Json(name = "description") + val description: String? = null, + /** + * The location of the event. + */ + @Json(name = "location") + val location: String? = null, + /** + * The timezone for displaying times in confirmation email messages and reminders. + */ + @Json(name = "timezone") + val timezone: String? = null, + /** + * The type of booking. + */ + @Json(name = "booking_type") + val bookingType: BookingType? = null, + /** + * Conference details for the event. + */ + @Json(name = "conferencing") + val conferencing: Conferencing? = null, + /** + * Whether Nylas sends email messages when an event is booked, cancelled, or rescheduled. + */ + @Json(name = "disable_emails") + val disableEmails: Boolean? = null, + /** + * The list of reminders to send to participants before the event starts. + */ + @Json(name = "reminders") + val reminders: List<BookingReminder>? = null, + /** + * Whether to hide participants from the event booking. + */ + @Json(name = "hide_participants") + val hideParticipants: Boolean? = null, +) { + /** + * Builder for [ConfigurationEventBooking]. + */ + class Builder { + private var title: String? = null + private var description: String? = null + private var location: String? = null + private var timezone: String? = null + private var bookingType: BookingType? = null + private var conferencing: Conferencing? = null + private var disableEmails: Boolean? = null + private var reminders: List<BookingReminder>? = null + private var hideParticipants: Boolean? = null + + /** + * Set the title of the event. + * @param title The title of the event. + * @return The builder. + */ + fun title(title: String?) = apply { this.title = title } + + /** + * Sets the description of the event. + * @param description The description of the event. + * @return The builder. + */ + fun description(description: String?) = apply { this.description = description } + + /** + * Sets the location of the event. + * @param location The location of the event. + * @return The builder. + */ + fun location(location: String?) = apply { this.location = location } + + /** + * Sets the timezone for displaying times in confirmation email messages and reminders. + * @param timezone The timezone for displaying times in confirmation email messages and reminders. + * @return The builder. + */ + fun timezone(timezone: String?) = apply { this.timezone = timezone } + + /** + * Sets the type of booking. + * @param bookingType The type of booking. + * @return The builder. + */ + fun bookingType(bookingType: BookingType?) = apply { this.bookingType = bookingType } + + /** + * Sets the conference details for the event. + * @param conferencing Conference details for the event. + * @return The builder. + */ + fun conferencing(conferencing: Conferencing?) = apply { this.conferencing = conferencing } + + /** + * Sets whether Nylas sends email messages when an event is booked, cancelled, or rescheduled. + * @param disableEmails Whether Nylas sends email messages when an event is booked, cancelled, or rescheduled. + * @return The builder. + */ + fun disableEmails(disableEmails: Boolean?) = apply { this.disableEmails = disableEmails } + + /** + * Sets the list of reminders to send to participants before the event starts. + * @param reminders The list of reminders to send to participants before the event starts. + * @return + */ + fun reminders(reminders: List<BookingReminder>?) = apply { this.reminders = reminders } + + /** + * Sets whether to hide participants from the event booking. + * @param hideParticipants Whether to hide participants from the event booking. + * @return The builder. + */ + fun hideParticipants(hideParticipants: Boolean?) = apply { this.hideParticipants = hideParticipants } + + /** + * Builds an [ConfigurationEventBooking] instance. + * @return The [ConfigurationEventBooking] instance. + */ + fun build() = ConfigurationEventBooking( + title, + description, + location, + timezone, + bookingType, + conferencing, + disableEmails, + reminders, + hideParticipants, + ) + } +} diff --git a/src/main/kotlin/com/nylas/models/ConfigurationParticipant.kt b/src/main/kotlin/com/nylas/models/ConfigurationParticipant.kt new file mode 100644 index 00000000..36afd68b --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ConfigurationParticipant.kt @@ -0,0 +1,100 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a participant in a scheduled event. + * @property email Email address of the participant. + * @property name Name of the participant. + * @property role Role of the participant. + * @property availability Availability data for the participant. + * @property booking Booking data for the participant. + * @property timezone Timezone of the participant. + */ +data class ConfigurationParticipant( + /** + * Email address of the participant. + */ + @Json(name = "email") + val email: String, + /** + * Name of the participant. + */ + @Json(name = "name") + val name: String? = null, + /** + * If true, the participant is the organizer of the event. + */ + @Json(name = "is_organizer") + val isOrganizer: Boolean? = null, + /** + * Availability data for the participant. + */ + @Json(name = "availability") + val availability: ConfigurationAvailabilityParticipant? = null, + /** + * Booking data for the participant. + */ + @Json(name = "booking") + val booking: ConfigurationBookingParticipant? = null, + /** + * Timezone of the participant. + */ + @Json(name = "timezone") + val timezone: String? = null, +) { + /** + * A builder for creating a [ConfigurationParticipant]. + * @param email Email address of the participant. + */ + data class Builder( + private val email: String, + ) { + private var name: String? = null + private var isOrganizer: Boolean? = null + private var availability: ConfigurationAvailabilityParticipant? = null + private var booking: ConfigurationBookingParticipant? = null + private var timezone: String? = null + + /** + * Set the name of the participant. + * @param name Name of the participant. + * @return The builder. + */ + fun name(name: String) = apply { this.name = name } + + /** + * Set if the participant is the organizer of the event. + * @param isOrganizer If true, the participant is the organizer of the event. + * @return The builder. + */ + fun isOrganizer(isOrganizer: Boolean) = apply { this.isOrganizer = isOrganizer } + + /** + * Set the availability data for the participant. + * @param availability Availability data for the participant. + * @return The builder. + */ + fun availability(availability: ConfigurationAvailabilityParticipant) = apply { this.availability = availability } + + /** + * Set the booking data for the participant. + * @param booking Booking data for the participant. + * @return The builder. + */ + fun booking(booking: ConfigurationBookingParticipant) = apply { this.booking = booking } + + /** + * Set the timezone of the participant. + * @param timezone Timezone of the participant. + * @return The builder. + */ + fun timezone(timezone: String) = apply { this.timezone = timezone } + + /** + * Build the [ConfigurationParticipant]. + * @return The [ConfigurationParticipant] + */ + fun build() = ConfigurationParticipant(email, name, isOrganizer, availability, booking, timezone) + } +} diff --git a/src/main/kotlin/com/nylas/models/ConfigurationSchedulerSettings.kt b/src/main/kotlin/com/nylas/models/ConfigurationSchedulerSettings.kt new file mode 100644 index 00000000..c67bb771 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ConfigurationSchedulerSettings.kt @@ -0,0 +1,333 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of scheduler settings. + */ +data class ConfigurationSchedulerSettings( + /** + * Definitions for additional fields to be displayed in the Scheduler UI. + */ + @Json(name = "additional_fields") + val additionalFields: Map<String, AdditionalField>? = null, + /** + * Number of days in the future that Scheduler is available for scheduling events. + */ + @Json(name = "available_days_in_future") + val availableDaysInFuture: Int? = null, + /** + * Minimum number of minutes in the future that a user can make a new booking. + */ + @Json(name = "min_booking_notice") + val minBookingNotice: Int? = null, + /** + * Minimum number of minutes before a booking can be cancelled. + */ + @Json(name = "min_cancellation_notice") + val minCancellationNotice: Int? = null, + /** + * A message about the cancellation policy to display when booking an event. + */ + @Json(name = "cancellation_policy") + val cancellationPolicy: String? = null, + /** + * The URL used to reschedule bookings. + */ + @Json(name = "rescheduling_url") + val reschedulingUrl: String? = null, + /** + * The URL used to cancel bookings. + */ + @Json(name = "cancellation_url") + val cancellationUrl: String? = null, + /** + * The URL used to confirm or cancel pending bookings. + */ + @Json(name = "organizer_confirmation_url") + val organizerConfirmationUrl: String? = null, + /** + * The custom URL to redirect to once the booking is confirmed. + */ + @Json(name = "confirmation_redirect_url") + val confirmationRedirectUrl: String? = null, + /** + * Whether the option to reschedule an event is hidden in booking confirmations and notifications. + */ + @Json(name = "hide_rescheduling_options") + val hideReschedulingOptions: Boolean? = null, + /** + * Whether the option to cancel an event is hidden in booking confirmations and notifications. + */ + @Json(name = "hide_cancellation_options") + val hideCancellationOptions: Boolean? = null, + /** + * Whether to hide the additional guests field on the scheduling page. + */ + @Json(name = "hide_additional_guests") + val hideAdditionalGuests: Boolean? = null, + /** + * Configurable settings for booking emails. + */ + @Json(name = "email_template") + val emailTemplate: EmailTemplate? = null, +) { + class Builder { + private var additionalFields: Map<String, AdditionalField>? = null + private var availableDaysInFuture: Int? = null + private var minBookingNotice: Int? = null + private var minCancellationNotice: Int? = null + private var cancellationPolicy: String? = null + private var reschedulingUrl: String? = null + private var cancellationUrl: String? = null + private var organizerConfirmationUrl: String? = null + private var confirmationRedirectUrl: String? = null + private var hideReschedulingOptions: Boolean? = null + private var hideCancellationOptions: Boolean? = null + private var hideAdditionalGuests: Boolean? = null + private var emailTemplate: EmailTemplate? = null + + /** + * Set the definitions for additional fields to be displayed in the Scheduler UI. + * + * @param additionalFields Definitions for additional fields to be displayed in the Scheduler UI. + * @return The builder. + */ + fun additionalFields(additionalFields: Map<String, AdditionalField>) = apply { this.additionalFields = additionalFields } + + /** + * Set the number of days in the future that Scheduler is available for scheduling events. + * + * @param availableDaysInFuture Number of days in the future that Scheduler is available for scheduling events. + * @return The builder. + */ + fun availableDaysInFuture(availableDaysInFuture: Int) = apply { this.availableDaysInFuture = availableDaysInFuture } + + /** + * Set the minimum number of minutes in the future that a user can make a new booking. + * + * @param minBookingNotice Minimum number of minutes in the future that a user can make a new booking. + * @return The builder. + */ + fun minBookingNotice(minBookingNotice: Int) = apply { this.minBookingNotice = minBookingNotice } + + /** + * Set the minimum number of minutes before a booking can be cancelled. + * + * @param minCancellationNotice Minimum number of minutes before a booking can be cancelled. + * @return The builder. + */ + fun minCancellationNotice(minCancellationNotice: Int) = apply { this.minCancellationNotice = minCancellationNotice } + + /** + * Set a message about the cancellation policy to display when booking an event. + * + * @param cancellationPolicy A message about the cancellation policy to display when booking an event. + * @return The builder. + */ + fun cancellationPolicy(cancellationPolicy: String) = apply { this.cancellationPolicy = cancellationPolicy } + + /** + * Set the URL used to reschedule bookings. + * + * @param reschedulingUrl The URL used to reschedule bookings. + * @return The builder. + */ + fun reschedulingUrl(reschedulingUrl: String) = apply { this.reschedulingUrl = reschedulingUrl } + + /** + * Set the URL used to cancel bookings. + * + * @param cancellationUrl The URL used to cancel bookings. + * @return The builder. + */ + fun cancellationUrl(cancellationUrl: String) = apply { this.cancellationUrl = cancellationUrl } + + /** + * Set the URL used to confirm or cancel pending bookings. + * + * @param organizerConfirmationUrl The URL used to confirm or cancel pending bookings. + * @return The builder. + */ + fun organizerConfirmationUrl(organizerConfirmationUrl: String) = apply { this.organizerConfirmationUrl = organizerConfirmationUrl } + + /** + * Set the custom URL to redirect to once the booking is confirmed. + * + * @param confirmationRedirectUrl The custom URL to redirect to once the booking is confirmed. + * @return The builder. + */ + fun confirmationRedirectUrl(confirmationRedirectUrl: String) = apply { this.confirmationRedirectUrl = confirmationRedirectUrl } + + /** + * Set whether the option to reschedule an event is hidden in booking confirmations and notifications. + * + * @param hideReschedulingOptions Whether the option to reschedule an event is hidden in booking confirmations and notifications. + * @return The builder. + */ + fun hideReschedulingOptions(hideReschedulingOptions: Boolean) = apply { this.hideReschedulingOptions = hideReschedulingOptions } + + /** + * Set whether the option to cancel an event is hidden in booking confirmations and notifications. + * + * @param hideCancellationOptions Whether the option to cancel an event is hidden in booking confirmations and notifications. + * @return The builder. + */ + fun hideCancellationOptions(hideCancellationOptions: Boolean) = apply { this.hideCancellationOptions = hideCancellationOptions } + + /** + * Set whether to hide the additional guests field on the scheduling page. + * + * @param hideAdditionalGuests Whether to hide the additional guests field on the scheduling page. + * @return The builder. + */ + fun hideAdditionalGuests(hideAdditionalGuests: Boolean) = apply { this.hideAdditionalGuests = hideAdditionalGuests } + + /** + * Set the configurable settings for booking emails. + * + * @param emailTemplate Configurable settings for booking emails. + * @return The builder. + */ + fun emailTemplate(emailTemplate: EmailTemplate) = apply { this.emailTemplate = emailTemplate } + + /** + * Build the [ConfigurationSchedulerSettings]. + * + * @return The [ConfigurationSchedulerSettings] + */ + fun build() = ConfigurationSchedulerSettings( + additionalFields, + availableDaysInFuture, + minBookingNotice, + minCancellationNotice, + cancellationPolicy, + reschedulingUrl, + cancellationUrl, + organizerConfirmationUrl, + confirmationRedirectUrl, + hideReschedulingOptions, + hideCancellationOptions, + hideAdditionalGuests, + emailTemplate, + ) + } +} + +/** + * Class representation of an additional field. + */ +data class AdditionalField( + /** + * The text label to be displayed in the Scheduler UI. + */ + @Json(name = "label") + val label: String, + /** + * The field type. + * Supported values are text, multi_line_text, email, phone_number, dropdown, date, checkbox, and radio_button. + */ + @Json(name = "type") + val type: AdditionalFieldType, + /** + * Whether the field is required to be filled out by the guest when booking an event. + */ + @Json(name = "required") + val required: Boolean, + /** + * A regular expression pattern that the value of the field must match. + */ + @Json(name = "pattern") + val pattern: String? = null, + /** + * The order in which the field will be displayed in the Scheduler UI. + * Fields with lower order values will be displayed first. + */ + @Json(name = "order") + val order: Int? = null, + /** + * A list of options for the dropdown or radio_button types. + * This field is required for the dropdown and radio_button types. + */ + @Json(name = "options") + val options: AdditonalFieldOptionsType? = null, +) + +/** + * Class representation of an email template. + */ +data class EmailTemplate( + /** + * Configurable settings specifically for booking confirmed emails. + */ + @Json(name = "booking_confirmed") + val bookingConfirmed: BookingConfirmedTemplate? = null, +) + +/** + * Class representation of booking confirmed template settings. + */ +data class BookingConfirmedTemplate( + /** + * The title to replace the default 'Booking Confirmed' title. + */ + @Json(name = "title") + val title: String? = null, + /** + * The additional body to be appended after the default body. + */ + @Json(name = "body") + val body: String? = null, +) + +/** + * Enum for additional field types. + */ +enum class AdditionalFieldType { + @Json(name = "text") + TEXT, + + @Json(name = "multi_line_text") + MULTI_LINE_TEXT, + + @Json(name = "email") + EMAIL, + + @Json(name = "phone_number") + PHONE_NUMBER, + + @Json(name = "dropdown") + DROPDOWN, + + @Json(name = "date") + DATE, + + @Json(name = "checkbox") + CHECKBOX, + + @Json(name = "radio_button") + RADIO_BUTTON, +} + +/** + * Enum for additional field options types. + */ +enum class AdditonalFieldOptionsType { + @Json(name = "text") + TEXT, + + @Json(name = "email") + EMAIL, + + @Json(name = "phone_number") + PHONE_NUMBER, + + @Json(name = "date") + DATE, + + @Json(name = "checkbox") + CHECKBOX, + + @Json(name = "radio_button") + RADIO_BUTTON, +} diff --git a/src/main/kotlin/com/nylas/models/ConfirmBookingQueryParams.kt b/src/main/kotlin/com/nylas/models/ConfirmBookingQueryParams.kt new file mode 100644 index 00000000..9f7f754d --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ConfirmBookingQueryParams.kt @@ -0,0 +1,60 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of the query parameters for confirming a booking. + */ +data class ConfirmBookingQueryParams( + /** + * The ID of the Configuration object whose settings are used for calculating availability. + */ + @Json(name = "configuration_id") + val configurationId: String? = null, + /** + * The slug of the Configuration object whose settings are used for calculating availability. + */ + @Json(name = "slug") + val slug: String? = null, + /** + * The client ID that was used to create the Configuration object. + */ + @Json(name = "client_id") + val clientId: String? = null, +) : IQueryParams { + /** + * Builder for [ConfirmBookingQueryParams]. + */ + class Builder { + private var configurationId: String? = null + private var slug: String? = null + private var clientId: String? = null + + /** + * Set the configuration ID of the booking. + * @param configurationId The configuration ID of the booking. + * @return The builder. + */ + fun configurationId(configurationId: String) = apply { this.configurationId = configurationId } + + /** + * Set the slug of the booking. + * @param slug The slug of the booking. + * @return The builder. + */ + fun slug(slug: String) = apply { this.slug = slug } + + /** + * Set the client ID of the booking. + * @param clientId The client ID of the booking. + * @return The builder. + */ + fun clientId(clientId: String) = apply { this.clientId = clientId } + + /** + * Builds a [ConfirmBookingQueryParams] instance. + * @return The [ConfirmBookingQueryParams] instance. + */ + fun build() = ConfirmBookingQueryParams(configurationId, slug, clientId) + } +} diff --git a/src/main/kotlin/com/nylas/models/ConfirmBookingRequest.kt b/src/main/kotlin/com/nylas/models/ConfirmBookingRequest.kt new file mode 100644 index 00000000..aa278d7f --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ConfirmBookingRequest.kt @@ -0,0 +1,57 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of the request body for confirming a booking. + */ +data class ConfirmBookingRequest( + @Json(name = "status") + val status: ConfirmBookingStatus? = null, + /** + * The salt extracted from the booking reference embedded in the organizer confirmation link. + */ + @Json(name = "salt") + val salt: String? = null, + /** + * The reason the booking is being cancelled. + */ + @Json(name = "cancellation_reason") + val cancellationReason: String? = null, +) { + /** + * Builder for [ConfirmBookingRequest]. + */ + class Builder { + private var status: ConfirmBookingStatus? = null + private var salt: String? = null + private var cancellationReason: String? = null + + /** + * Set the status of the booking. + * @param status The status of the booking. + * @return The builder. + */ + fun status(status: ConfirmBookingStatus) = apply { this.status = status } + + /** + * Set the salt of the booking. + * @param salt The salt of the booking. + * @return The builder. + */ + fun salt(salt: String) = apply { this.salt = salt } + + /** + * Set the cancellation reason of the booking. + * @param cancellationReason The cancellation reason of the booking. + * @return The builder. + */ + fun cancellationReason(cancellationReason: String) = apply { this.cancellationReason = cancellationReason } + + /** + * Builds a [ConfirmBookingRequest] instance. + * @return The [ConfirmBookingRequest] instance. + */ + fun build() = ConfirmBookingRequest(status, salt, cancellationReason) + } +} diff --git a/src/main/kotlin/com/nylas/models/ConfirmBookingStatus.kt b/src/main/kotlin/com/nylas/models/ConfirmBookingStatus.kt new file mode 100644 index 00000000..b8d5c937 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ConfirmBookingStatus.kt @@ -0,0 +1,14 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Enum for confirm booking statuses. + */ +enum class ConfirmBookingStatus { + @Json(name = "confirmed") + CONFIRMED, + + @Json(name = "cancelled") + CANCELLED, +} diff --git a/src/main/kotlin/com/nylas/models/CreateBookingGuest.kt b/src/main/kotlin/com/nylas/models/CreateBookingGuest.kt new file mode 100644 index 00000000..69deedc5 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/CreateBookingGuest.kt @@ -0,0 +1,41 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a request to create a booking guest. + */ +data class CreateBookingGuest( + /** + * The email address of the guest. + */ + @Json(name = "email") + val email: String, + /** + * The name of the guest. + */ + @Json(name = "name") + val name: String? = null, +) { + /** + * Builder for [CreateBookingGuest]. + */ + data class Builder( + private val email: String, + ) { + private var name: String? = null + + /** + * Set the name of the guest. + * @param name The name of the guest. + * @return The builder. + */ + fun name(name: String) = apply { this.name = name } + + /** + * Builds a [CreateBookingGuest] instance. + * @return The [CreateBookingGuest] instance. + */ + fun build() = CreateBookingGuest(email, name) + } +} diff --git a/src/main/kotlin/com/nylas/models/CreateBookingOrganizer.kt b/src/main/kotlin/com/nylas/models/CreateBookingOrganizer.kt new file mode 100644 index 00000000..ddf441e6 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/CreateBookingOrganizer.kt @@ -0,0 +1,41 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representing a request to create a booking organizer. + */ +data class CreateBookingOrganizer( + /** + * The email address of the participant designated as the organizer of the event. + */ + @Json(name = "email") + val email: String, + /** + * The name of the participant designated as the organizer of the event. + */ + @Json(name = "name") + val name: String? = null, +) { + /** + * Builder for [CreateBookingOrganizer]. + */ + data class Builder( + private val email: String, + ) { + private var name: String? = null + + /** + * Set the name of the participant designated as the organizer of the event. + * @param name The name of the participant designated as the organizer of the event. + * @return The builder. + */ + fun name(name: String) = apply { this.name = name } + + /** + * Builds a [CreateBookingOrganizer] instance. + * @return The [CreateBookingOrganizer] instance. + */ + fun build() = CreateBookingOrganizer(email, name) + } +} diff --git a/src/main/kotlin/com/nylas/models/CreateBookingQueryParams.kt b/src/main/kotlin/com/nylas/models/CreateBookingQueryParams.kt new file mode 100644 index 00000000..59a9eb06 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/CreateBookingQueryParams.kt @@ -0,0 +1,60 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of the query parameters for creating a booking. + */ +data class CreateBookingQueryParams( + /** + * The ID of the Configuration object whose settings are used for calculating availability. + */ + @Json(name = "configuration_id") + val configurationId: String? = null, + /** + * The slug of the Configuration object whose settings are used for calculating availability. + */ + @Json(name = "slug") + val slug: String? = null, + /** + * The client ID that was used to create the Configuration object. + */ + @Json(name = "client_id") + val clientId: String? = null, +) : IQueryParams { + /** + * Builder for [CreateBookingQueryParams]. + */ + class Builder { + private var configurationId: String? = null + private var slug: String? = null + private var clientId: String? = null + + /** + * Sets the ID of the Configuration object whose settings are used for calculating availability. + * @param configurationId The ID of the Configuration object whose settings are used for calculating availability. + * @return The builder. + */ + fun configurationId(configurationId: String) = apply { this.configurationId = configurationId } + + /** + * Sets the slug of the Configuration object whose settings are used for calculating availability. + * @param slug The slug of the Configuration object whose settings are used for calculating availability. + * @return The builder. + */ + fun slug(slug: String) = apply { this.slug = slug } + + /** + * Sets the client ID that was used to create the Configuration object. + * @param clientId The client ID that was used to create the Configuration object. + * @return The builder. + */ + fun clientId(clientId: String) = apply { this.clientId = clientId } + + /** + * Builds a [CreateBookingQueryParams] instance. + * @return The [CreateBookingQueryParams] instance. + */ + fun build() = CreateBookingQueryParams(configurationId, slug, clientId) + } +} diff --git a/src/main/kotlin/com/nylas/models/CreateBookingReminder.kt b/src/main/kotlin/com/nylas/models/CreateBookingReminder.kt new file mode 100644 index 00000000..40f2d3a9 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/CreateBookingReminder.kt @@ -0,0 +1,60 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a request to create a booking reminder. + */ +data class CreateBookingReminder( + /** + * The reminder type. + */ + @Json(name = "type") + val type: String, + /** + * The number of minutes before the event to send the reminder. + */ + @Json(name = "minutes_before_event") + val minutesBeforeEvent: Int, + /** + * The recipient of the reminder. + */ + @Json(name = "recipient") + val recipient: String? = null, + /** + * The subject of the email reminder. + */ + @Json(name = "email_subject") + val emailSubject: String? = null, +) { + /** + * Builder for [CreateBookingReminder]. + */ + data class Builder( + private val type: String, + private val minutesBeforeEvent: Int, + ) { + private var recipient: String? = null + private var emailSubject: String? = null + + /** + * Set the recipient of the reminder. + * @param recipient The recipient of the reminder. + * @return The builder. + */ + fun recipient(recipient: String) = apply { this.recipient = recipient } + + /** + * Set the subject of the email reminder. + * @param emailSubject The subject of the email reminder. + * @return The builder. + */ + fun emailSubject(emailSubject: String) = apply { this.emailSubject = emailSubject } + + /** + * Builds a [CreateBookingReminder] instance. + * @return The [CreateBookingReminder] instance. + */ + fun build() = CreateBookingReminder(type, minutesBeforeEvent, recipient, emailSubject) + } +} diff --git a/src/main/kotlin/com/nylas/models/CreateBookingRequest.kt b/src/main/kotlin/com/nylas/models/CreateBookingRequest.kt new file mode 100644 index 00000000..a3879f4a --- /dev/null +++ b/src/main/kotlin/com/nylas/models/CreateBookingRequest.kt @@ -0,0 +1,127 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a confirm booking request. + */ +data class CreateBookingRequest( + /** + * The event's start time, in Unix epoch format. + */ + @Json(name = "start_time") + val startTime: String? = null, + /** + * The event's end time, in Unix epoch format. + */ + @Json(name = "end_time") + val endTime: String? = null, + /** + * An array of objects that include a list of participant + * email addresses from the Configuration object to include in the booking. + * If not provided, Nylas includes all participants from the Configuration object. + */ + @Json(name = "participants") + val participants: List<BookingParticipant>? = null, + /** + * Details about the guest that is creating the booking. The guest name and email are required. + */ + @Json(name = "guest") + val guest: BookingGuest? = null, + /** + * The guest's timezone that is used in email notifications. + */ + @Json(name = "timezone") + val timezone: String? = null, + /** + * The language of the guest's email notifications. + */ + @Json(name = "email_language") + val emailLanguage: EmailLanguage? = null, + /** + * An array of objects that include a list of additional guest email addresses to include in the booking. + */ + @Json(name = "additional_guests") + val additionalGuests: List<BookingGuest>? = null, + /** + * A dictionary of additional field keys mapped to the values populated by the guest in the booking form. + */ + @Json(name = "additional_fields") + val additionalFields: Map<String, String>? = null, +) { + /** + * Builder for [CreateBookingRequest]. + */ + class Builder { + private var startTime: String? = null + private var endTime: String? = null + private var participants: List<BookingParticipant>? = null + private var guest: BookingGuest? = null + private var timezone: String? = null + private var emailLanguage: EmailLanguage? = null + private var additionalGuests: List<BookingGuest>? = null + private var additionalFields: Map<String, String>? = null + + /** + * Set the start time of the booking. + * @param startTime The start time of the booking. + * @return The builder. + */ + fun startTime(startTime: String) = apply { this.startTime = startTime } + + /** + * Set the end time of the booking. + * @param endTime The end time of the booking. + * @return The builder. + */ + fun endTime(endTime: String) = apply { this.endTime = endTime } + + /** + * Set the participants of the booking. + * @param participants The participants of the booking. + * @return The builder. + */ + fun participants(participants: List<BookingParticipant>) = apply { this.participants = participants } + + /** + * Set the guests of the booking. + * @param guests The guests of the booking. + * @return The builder. + */ + fun guest(guest: BookingGuest) = apply { this.guest = guest } + + /** + * Set the timezone of the booking. + * @param timezone The timezone of the booking. + * @return The builder. + */ + fun timezone(timezone: String) = apply { this.timezone = timezone } + + /** + * Set the email language of the booking. + * @param emailLanguage The email language of the booking. + * @return The builder. + */ + fun emailLanguage(emailLanguage: EmailLanguage) = apply { this.emailLanguage = emailLanguage } + + /** + * Set the additional guests of the booking. + * @param additionalGuests The additional guests of the booking. + * @return The builder. + */ + fun additionalGuests(additionalGuests: List<BookingGuest>) = apply { this.additionalGuests = additionalGuests } + + /** + * Set the additional fields of the booking. + * @param additionalFields The additional fields of the booking. + * @return The builder. + */ + fun additionalFields(additionalFields: Map<String, String>) = apply { this.additionalFields = additionalFields } + + /** + * Builds a [CreateBookingRequest] instance. + * @return The [CreateBookingRequest] instance. + */ + fun build() = CreateBookingRequest(startTime, endTime, participants, guest, timezone, emailLanguage, additionalGuests, additionalFields) + } +} diff --git a/src/main/kotlin/com/nylas/models/CreateConfigurationRequest.kt b/src/main/kotlin/com/nylas/models/CreateConfigurationRequest.kt new file mode 100644 index 00000000..763dabd8 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/CreateConfigurationRequest.kt @@ -0,0 +1,108 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a request to create a configuration. + */ +data class CreateConfigurationRequest( + /** + * List of participants included in the scheduled event. + */ + @Json(name = "participants") + val participants: List<ConfigurationParticipant>, + /** + * Rules that determine available time slots for the event. + */ + @Json(name = "availability") + val availability: ConfigurationAvailability, + /** + * Booking data for the event. + */ + @Json(name = "event_booking") + val eventBooking: ConfigurationEventBooking, + /** + * Unique identifier for the Configuration object. + */ + @Json(name = "slug") + val slug: String? = null, + /** + * If true, scheduling Availability and Bookings endpoints require a valid session ID. + */ + @Json(name = "requires_session_auth") + val requiresSessionAuth: Boolean? = null, + /** + * Settings for the Scheduler UI. + */ + @Json(name = "scheduler") + val scheduler: ConfigurationSchedulerSettings? = null, + /** + * Appearance settings for the Scheduler UI. + */ + @Json(name = "appearance") + val appearance: Map<String, String>? = null, +) { + /** + * A builder for creating a [CreateConfigurationRequest]. + * @param participants List of participants included in the scheduled event. + * @param availability Rules that determine available time slots for the event. + * @param eventBooking Booking data for the event. + */ + data class Builder( + private val participants: List<ConfigurationParticipant>, + private val availability: ConfigurationAvailability, + private val eventBooking: ConfigurationEventBooking, + ) { + private var requiresSessionAuth: Boolean? = null + private var slug: String? = null + private var scheduler: ConfigurationSchedulerSettings? = null + private var appearance: Map<String, String>? = null + + /** + * Set the unique identifier for the configuration. + * + * @param slug Unique identifier for the Configuration object. + * @return The builder + */ + fun slug(slug: String) = apply { this.slug = slug } + + /** + * Set if scheduling Availability and Bookings endpoints require a valid session ID. + * + * @param requiresSessionAuth If true, scheduling Availability and Bookings endpoints require a valid session ID. + * @return The builder + */ + fun requiresSessionAuth(requiresSessionAuth: Boolean) = apply { this.requiresSessionAuth = requiresSessionAuth } + + /** + * Set the settings for the Scheduler UI. + * + * @param scheduler Settings for the Scheduler UI. + * @return The builder + */ + fun scheduler(scheduler: ConfigurationSchedulerSettings) = apply { this.scheduler = scheduler } + + /** + * Set the appearance settings for the Scheduler UI. + * + * @param appearance Appearance settings for the Scheduler UI. + * @return The builder + */ + fun appearance(appearance: Map<String, String>) = apply { this.appearance = appearance } + + /** + * Build the [CreateConfigurationRequest]. + * + * @return The [CreateConfigurationRequest] + */ + fun build() = CreateConfigurationRequest( + participants, + availability, + eventBooking, + slug, + requiresSessionAuth, + scheduler, + appearance, + ) + } +} diff --git a/src/main/kotlin/com/nylas/models/CreateSessionRequest.kt b/src/main/kotlin/com/nylas/models/CreateSessionRequest.kt new file mode 100644 index 00000000..b47a8b39 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/CreateSessionRequest.kt @@ -0,0 +1,64 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a request to create a session. + */ +data class CreateSessionRequest( + /** + * The identifier of the Configuration to act upon. If you're using slug, configuration_id is not required. + */ + @Json(name = "configuration_id") + val configurationId: String? = null, + /** + * The time to live for the session. + */ + @Json(name = "time_to_live") + val timeToLive: Int? = null, + + /** + * The slug of the Scheduler Configuration object for the session. You can use slug instead of configuration_id + */ + @Json(name = "slug") + val slug: String? = null, +) { + /** + * A builder for creating a [CreateSessionRequest]. + * @param configurationId The identifier of the Configuration to act upon. + * @param timeToLive The time to live for the session. + * @param slug The slug of the Scheduler Configuration object for the session. + */ + class Builder { + private var configurationId: String? = null + private var timeToLive: Int? = null + private var slug: String? = null + + /** + * Set the configuration ID. + * @param configurationId The identifier of the Configuration to act upon. + * @return The builder. + */ + fun configurationId(configurationId: String) = apply { this.configurationId = configurationId } + + /** + * Set the time to live for the session. + * @param timeToLive The time to live for the session. + * @return The builder. + */ + fun timeToLive(timeToLive: Int) = apply { this.timeToLive = timeToLive } + + /** + * Set the slug of the Scheduler Configuration object for the session. + * @param slug The slug of the Scheduler Configuration object for the session. + * @return The builder. + */ + fun slug(slug: String) = apply { this.slug = slug } + + /** + * Build the [CreateSessionRequest]. + * @return The [CreateSessionRequest]. + */ + fun build() = CreateSessionRequest(configurationId, timeToLive, slug) + } +} diff --git a/src/main/kotlin/com/nylas/models/DestroyBookingQueryParams.kt b/src/main/kotlin/com/nylas/models/DestroyBookingQueryParams.kt new file mode 100644 index 00000000..34b31e71 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/DestroyBookingQueryParams.kt @@ -0,0 +1,60 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of the query parameters for destroying a booking. + */ +data class DestroyBookingQueryParams( + /** + * The ID of the Configuration object whose settings are used for calculating availability. + */ + @Json(name = "configuration_id") + val configurationId: String? = null, + /** + * The slug of the Configuration object whose settings are used for calculating availability. + */ + @Json(name = "slug") + val slug: String? = null, + /** + * The client ID that was used to create the Configuration object. + */ + @Json(name = "client_id") + val clientId: String? = null, +) : IQueryParams { + /** + * Builder for [DestroyBookingQueryParams]. + */ + class Builder { + private var configurationId: String? = null + private var slug: String? = null + private var clientId: String? = null + + /** + * Sets the ID of the Configuration object whose settings are used for calculating availability. + * @param configurationId The ID of the Configuration object whose settings are used for calculating availability. + * @return The builder. + */ + fun configurationId(configurationId: String) = apply { this.configurationId = configurationId } + + /** + * Sets the slug of the Configuration object whose settings are used for calculating availability. + * @param slug The slug of the Configuration object whose settings are used for calculating availability. + * @return The builder. + */ + fun slug(slug: String) = apply { this.slug = slug } + + /** + * Sets the client ID that was used to create the Configuration object. + * @param clientId The client ID that was used to create the Configuration object. + * @return The builder. + */ + fun clientId(clientId: String) = apply { this.clientId = clientId } + + /** + * Builds a [DestroyBookingQueryParams] instance. + * @return The [DestroyBookingQueryParams] instance. + */ + fun build() = DestroyBookingQueryParams(configurationId, slug, clientId) + } +} diff --git a/src/main/kotlin/com/nylas/models/DestroyBookingRequest.kt b/src/main/kotlin/com/nylas/models/DestroyBookingRequest.kt new file mode 100644 index 00000000..51d86cac --- /dev/null +++ b/src/main/kotlin/com/nylas/models/DestroyBookingRequest.kt @@ -0,0 +1,27 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a request to destroy a booking. + */ +data class DestroyBookingRequest( + /** + * The reason for the cancellation of the booking. + */ + @Json(name = "cancellation_reason") + val cancellationReason: String, +) { + /** + * Builder for [DestroyBookingRequest]. + */ + data class Builder( + private val cancellationReason: String, + ) { + /** + * Builds a [DestroyBookingRequest] instance. + * @return The [DestroyBookingRequest] instance. + */ + fun build() = DestroyBookingRequest(cancellationReason) + } +} diff --git a/src/main/kotlin/com/nylas/models/EmailLanguage.kt b/src/main/kotlin/com/nylas/models/EmailLanguage.kt new file mode 100644 index 00000000..ff97cfff --- /dev/null +++ b/src/main/kotlin/com/nylas/models/EmailLanguage.kt @@ -0,0 +1,32 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Enum for email language options. + */ +enum class EmailLanguage { + @Json(name = "en") + EN, + + @Json(name = "es") + ES, + + @Json(name = "fr") + FR, + + @Json(name = "de") + DE, + + @Json(name = "nl") + NL, + + @Json(name = "sv") + SV, + + @Json(name = "ja") + JA, + + @Json(name = "zh") + ZH, +} diff --git a/src/main/kotlin/com/nylas/models/FindBookingQueryParams.kt b/src/main/kotlin/com/nylas/models/FindBookingQueryParams.kt new file mode 100644 index 00000000..cf728812 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/FindBookingQueryParams.kt @@ -0,0 +1,63 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of the query parameters for finding a booking. + */ +data class FindBookingQueryParams( + /** + * The ID of the Configuration object whose settings are used for calculating availability. + * If you're using session authentication (requires_session_auth is set to true), configuration_id is not required + */ + @Json(name = "configuration_id") + val configurationId: String? = null, + /** + * The slug of the Configuration object whose settings are used for calculating availability. + * If you're using session authentication (requires_session_auth is set to true), or using configuration_id, slug is not required + */ + @Json(name = "slug") + val slug: String? = null, + /** + * The client ID that was used to create the Configuration object. + * client_id is required only if using slug. + */ + @Json(name = "client_id") + val clientId: String? = null, +) : IQueryParams { + /** + * Builder for [FindBookingQueryParams]. + */ + class Builder { + private var configurationId: String? = null + private var slug: String? = null + private var clientId: String? = null + + /** + * Sets the ID of the Configuration object whose settings are used for calculating availability. + * @param configurationId The ID of the Configuration object whose settings are used for calculating availability. + * @return The builder. + */ + fun configurationId(configurationId: String) = apply { this.configurationId = configurationId } + + /** + * Sets the slug of the Configuration object whose settings are used for calculating availability. + * @param slug The slug of the Configuration object whose settings are used for calculating availability. + * @return The builder. + */ + fun slug(slug: String) = apply { this.slug = slug } + + /** + * Sets the client ID that was used to create the Configuration object. + * @param clientId The client ID that was used to create the Configuration object. + * @return The builder. + */ + fun clientId(clientId: String) = apply { this.clientId = clientId } + + /** + * Builds a [FindBookingQueryParams] instance. + * @return The [FindBookingQueryParams] instance. + */ + fun build() = FindBookingQueryParams(configurationId, slug, clientId) + } +} diff --git a/src/main/kotlin/com/nylas/models/ListConfigurationsQueryParams.kt b/src/main/kotlin/com/nylas/models/ListConfigurationsQueryParams.kt new file mode 100644 index 00000000..29656c5c --- /dev/null +++ b/src/main/kotlin/com/nylas/models/ListConfigurationsQueryParams.kt @@ -0,0 +1,50 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +data class ListConfigurationsQueryParams( + /** + * The maximum number of objects to return. + * Defaults to 50. The maximum allowed value is 200. + */ + @Json(name = "limit") + val limit: Int? = null, + /** + * An identifier that specifies which page of data to return. + * This value should be taken from the [ListResponse.nextCursor] response field. + */ + @Json(name = "page_token") + val pageToken: String? = null, +) : IQueryParams + +/** + * Builder for [ListConfigurationsQueryParams]. + */ +class Builder { + private var limit: Int? = null + private var pageToken: String? = null + + /** + * Sets the maximum number of objects to return. + * This field defaults to 50. The maximum allowed value is 200. + * @param limit The maximum number of objects to return. + * @return The builder. + */ + + fun limit(limit: Int?) = apply { this.limit = limit } + + /** + * Sets the identifier that specifies which page of data to return. + * This value should be taken from the next_cursor response field. + * @param pageToken The identifier that specifies which page of data to return. + * @return The builder. + */ + + fun pageToken(pageToken: String?) = apply { this.pageToken = pageToken } + + /** + * Builds a [ListConfigurationsQueryParams] instance. + * @return The [ListConfigurationsQueryParams] instance. + */ + fun build() = ListConfigurationsQueryParams(limit, pageToken) +} diff --git a/src/main/kotlin/com/nylas/models/RescheduleBookingQueryParams.kt b/src/main/kotlin/com/nylas/models/RescheduleBookingQueryParams.kt new file mode 100644 index 00000000..74228046 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/RescheduleBookingQueryParams.kt @@ -0,0 +1,55 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of the query parameters for rescheduling a booking. + */ +data class RescheduleBookingQueryParams( + /** + * The ID of the Configuration object whose settings are used for calculating availability. + */ + @Json(name = "configuration_id") + val configurationId: String, + /** + * The slug of the Configuration object whose settings are used for calculating availability. + */ + @Json(name = "slug") + val slug: String, + /** + * The client ID that was used to create the Configuration object. + */ + @Json(name = "client_id") + val clientId: String, +) : IQueryParams { + /** + * Builder for [RescheduleBookingQueryParams]. + */ + class Builder { + private var configurationId: String? = null + private var slug: String? = null + private var clientId: String? = null + + /** + * Sets the ID of the Configuration object whose settings are used for calculating availability. + * @param configurationId The ID of the Configuration object whose settings are used for calculating availability. + * @return The builder. + */ + fun configurationId(configurationId: String) = apply { this.configurationId = configurationId } + + /** + * Sets the slug of the Configuration object whose settings are used for calculating availability. + * @param slug The slug of the Configuration object whose settings are used for calculating availability. + * @return The builder. + */ + fun slug(slug: String) = apply { this.slug = slug } + + /** + * Sets the client ID that was used to create the Configuration object. + * @param clientId The client ID that was used to create the Configuration object. + * @return The builder. + */ + fun clientId(clientId: String) = apply { this.clientId = clientId } + } + fun build() = RescheduleBookingQueryParams(configurationId, slug, clientId) +} diff --git a/src/main/kotlin/com/nylas/models/RescheduleBookingRequest.kt b/src/main/kotlin/com/nylas/models/RescheduleBookingRequest.kt new file mode 100644 index 00000000..d0bfdd62 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/RescheduleBookingRequest.kt @@ -0,0 +1,44 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +data class RescheduleBookingRequest( + /** + * The event's start time, in Unix epoch format. + */ + @Json(name = "start_time") + val startTime: Int? = null, + /** + * The event's end time, in Unix epoch format. + */ + @Json(name = "end_time") + val endTime: Int? = null, +) { + /** + * Builder for [RescheduleBookingRequest]. + */ + class Builder { + private var startTime: Int? = null + private var endTime: Int? = null + + /** + * Set the start time of the booking. + * @param startTime The start time of the booking. + * @return The builder. + */ + fun startTime(startTime: Int) = apply { this.startTime = startTime } + + /** + * Set the end time of the booking. + * @param endTime The end time of the booking. + * @return The builder. + */ + fun endTime(endTime: Int) = apply { this.endTime = endTime } + + /** + * Builds a [RescheduleBookingRequest] instance. + * @return The [RescheduleBookingRequest] instance. + */ + fun build() = RescheduleBookingRequest(startTime, endTime) + } +} diff --git a/src/main/kotlin/com/nylas/models/Scheduler.kt b/src/main/kotlin/com/nylas/models/Scheduler.kt new file mode 100644 index 00000000..026491c9 --- /dev/null +++ b/src/main/kotlin/com/nylas/models/Scheduler.kt @@ -0,0 +1,104 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a Nylas scheduler configuration. + */ +data class Configuration( + /** + * Globally unique object identifier. + */ + @Json(name = "id") + val id: String, + /** + * List of participants included in the scheduled event. + */ + @Json(name = "participants") + val participants: List<ConfigurationParticipant>, + /** + * Rules that determine available time slots for the event. + */ + @Json(name = "availability") + val availability: ConfigurationAvailability, + /** + * Booking data for the event. + */ + @Json(name = "event_booking") + val eventBooking: ConfigurationEventBooking, + /** + * Unique identifier for the Configuration object. + */ + @Json(name = "slug") + val slug: String? = null, + /** + * If true, scheduling Availability and Bookings endpoints require a valid session ID. + */ + @Json(name = "requires_session_auth") + val requiresSessionAuth: Boolean? = null, + /** + * Settings for the Scheduler UI. + */ + @Json(name = "scheduler") + val scheduler: ConfigurationSchedulerSettings? = null, + /** + * Appearance settings for the Scheduler UI. + */ + @Json(name = "appearance") + val appearance: Map<String, String>? = null, +) + +/** + * Class representation of a session. + */ +data class Session( + /** + * The ID of the session. + */ + @Json(name = "session_id") + val sessionId: String, +) + +/** + * Class representation of a booking. + */ +data class Booking( + /** + * The unique ID of the booking. + */ + @Json(name = "booking_id") + val bookingId: String, + /** + * The unique ID of the event associated with the booking. + */ + @Json(name = "event_id") + val eventId: String, + /** + * The title of the event. + */ + @Json(name = "title") + val title: String, + /** + * The participant designated as the organizer of the event. + */ + @Json(name = "organizer") + val organizer: BookingOrganizer, + /** + * The current status of the booking. + */ + @Json(name = "status") + val status: BookingStatus, + /** + * The description of the event. + */ + @Json(name = "description") + val description: String? = null, +) + +/** + * Class representation of a booking participant. + */ +data class BookingParticipant( + @Json(name = "email") + val email: String, +) diff --git a/src/main/kotlin/com/nylas/models/UpdateConfigurationRequest.kt b/src/main/kotlin/com/nylas/models/UpdateConfigurationRequest.kt new file mode 100644 index 00000000..3386ee0f --- /dev/null +++ b/src/main/kotlin/com/nylas/models/UpdateConfigurationRequest.kt @@ -0,0 +1,125 @@ +package com.nylas.models + +import com.squareup.moshi.Json + +/** + * Class representation of a request to update a configuration. + */ +data class UpdateConfigurationRequest( + /** + * List of participants included in the scheduled event. + */ + @Json(name = "participants") + val participants: List<ConfigurationParticipant>? = null, + /** + * Rules that determine available time slots for the event. + */ + @Json(name = "availability") + val availability: ConfigurationAvailability? = null, + /** + * Booking data for the event. + */ + @Json(name = "event_booking") + val eventBooking: ConfigurationEventBooking? = null, + /** + * Unique identifier for the Configuration object. + */ + @Json(name = "slug") + val slug: String? = null, + /** + * If true, scheduling Availability and Bookings endpoints require a valid session ID. + */ + @Json(name = "requires_session_auth") + val requiresSessionAuth: Boolean? = null, + /** + * Settings for the Scheduler UI. + */ + @Json(name = "scheduler") + val scheduler: ConfigurationSchedulerSettings? = null, + /** + * Appearance settings for the Scheduler UI. + */ + @Json(name = "appearance") + val appearance: Map<String, String>? = null, +) { + /** + * A builder for creating a [UpdateConfigurationRequest]. + */ + class Builder { + private var participants: List<ConfigurationParticipant>? = null + private var availability: ConfigurationAvailability? = null + private var eventBooking: ConfigurationEventBooking? = null + private var requiresSessionAuth: Boolean? = null + private var slug: String? = null + private var scheduler: ConfigurationSchedulerSettings? = null + private var appearance: Map<String, String>? = null + + /** + * Set the list of participants included in the scheduled event. + * @param participants List of participants included in the scheduled event. + * @return The builder + */ + fun participants(participants: List<ConfigurationParticipant>) = apply { this.participants = participants } + + /** + * Set the rules that determine available time slots for the event. + * @param availability Rules that determine available time slots for the event. + * @return The builder + */ + fun availability(availability: ConfigurationAvailability) = apply { this.availability = availability } + + /** + * Set the booking data for the event. + * @param eventBooking Booking data for the event. + * @return The builder + */ + fun eventBooking(eventBooking: ConfigurationEventBooking) = apply { this.eventBooking = eventBooking } + + /** + * Set the unique identifier for the configuration. + * + * @param slug Unique identifier for the Configuration object. + * @return The builder + */ + fun slug(slug: String) = apply { this.slug = slug } + + /** + * Set if scheduling Availability and Bookings endpoints require a valid session ID. + * + * @param requiresSessionAuth If true, scheduling Availability and Bookings endpoints require a valid session ID. + * @return The builder + */ + fun requiresSessionAuth(requiresSessionAuth: Boolean) = apply { this.requiresSessionAuth = requiresSessionAuth } + + /** + * Set the settings for the Scheduler UI. + * + * @param scheduler Settings for the Scheduler UI. + * @return The builder + */ + fun scheduler(scheduler: ConfigurationSchedulerSettings) = apply { this.scheduler = scheduler } + + /** + * Set the appearance settings for the Scheduler UI. + * + * @param appearance Appearance settings for the Scheduler UI. + * @return The builder + */ + fun appearance(appearance: Map<String, String>) = apply { this.appearance = appearance } + + /** + * Build the [UpdateConfigurationRequest]. + * + * @return The [UpdateConfigurationRequest] + */ + fun build() = UpdateConfigurationRequest( + participants, + availability, + eventBooking, + slug, + requiresSessionAuth, + scheduler, + appearance, + ) + } +} diff --git a/src/main/kotlin/com/nylas/resources/Bookings.kt b/src/main/kotlin/com/nylas/resources/Bookings.kt new file mode 100644 index 00000000..bdebdd7f --- /dev/null +++ b/src/main/kotlin/com/nylas/resources/Bookings.kt @@ -0,0 +1,107 @@ +package com.nylas.resources + +import com.nylas.NylasClient +import com.nylas.models.* +import com.nylas.util.JsonHelper + +/** + * Nylas Bookings API + * + * The Nylas Bookings API allows you to create new bookings or manage existing ones, as well as getting + * bookings details for a user. + */ +class Bookings(client: NylasClient) : Resource<Booking>(client, Booking::class.java) { + /** + * Find a booking + * @param bookingId The ID of the booking to find. + * @param queryParams Optional query parameters to apply + * @param overrides Optional request overrides to apply + * @return The Booking object + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun find( + bookingId: String, + queryParams: FindBookingQueryParams? = null, + overrides: RequestOverrides? = null, + ): Response<Booking> { + val path = String.format("v3/scheduling/bookings/%s", bookingId) + return findResource(path, queryParams, overrides = overrides) + } + + /** + * Create a booking + * @param requestBody The data to create the booking with. + * @param queryParams Optional query parameters to apply + * @param overrides Optional request overrides to apply + * @return The Booking object + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun create( + requestBody: CreateBookingRequest, + queryParams: CreateBookingQueryParams? = null, + overrides: RequestOverrides? = null, + ): Response<Booking> { + val path = "v3/scheduling/bookings" + val adapter = JsonHelper.moshi().adapter(CreateBookingRequest::class.java) + val serializedRequestBody = adapter.toJson(requestBody) + return createResource(path, serializedRequestBody, queryParams, overrides = overrides) + } + + /** + * Confirm a booking + * @param bookingId The ID of the booking to update. + * @param requestBody The data to update the booking with. + * @param queryParams Optional query parameters to apply + * @param overrides Optional request overrides to apply + * @return The Booking object + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun confirm( + bookingId: String, + requestBody: ConfirmBookingRequest, + queryParams: ConfirmBookingQueryParams? = null, + overrides: RequestOverrides? = null, + ): Response<Booking> { + val path = String.format("v3/scheduling/bookings/%s", bookingId) + val adapter = JsonHelper.moshi().adapter(ConfirmBookingRequest::class.java) + val serializedRequestBody = adapter.toJson(requestBody) + return updateResource(path, serializedRequestBody, queryParams, overrides = overrides) + } + + /** + * Reschedule a booking + * @param bookingId The ID of the booking to update. + * @param requestBody The data to update the booking with. + * @param queryParams Optional query parameters to apply + * @param overrides Optional request overrides to apply + * @return The Booking object + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun reschedule( + bookingId: String, + requestBody: RescheduleBookingRequest, + queryParams: RescheduleBookingQueryParams? = null, + overrides: RequestOverrides? = null, + ): Response<Booking> { + val path = String.format("v3/scheduling/bookings/%s", bookingId) + val adapter = JsonHelper.moshi().adapter(RescheduleBookingRequest::class.java) + val serializedRequestBody = adapter.toJson(requestBody) + return patchResource(path, serializedRequestBody, queryParams, overrides = overrides) + } + + /** + * Destroy a booking + * @param bookingId The ID of the booking to destroy. + * @param queryParams Optional query parameters to apply + * @param overrides Optional request overrides to apply + * @return The DeleteResponse object + */ + fun destroy(bookingId: String, queryParams: DestroyBookingQueryParams? = null, overrides: RequestOverrides? = null): DeleteResponse { + val path = String.format("v3/scheduling/bookings/%s", bookingId) + return destroyResource(path, queryParams, overrides = overrides) + } +} diff --git a/src/main/kotlin/com/nylas/resources/Configurations.kt b/src/main/kotlin/com/nylas/resources/Configurations.kt new file mode 100644 index 00000000..cffc1ee4 --- /dev/null +++ b/src/main/kotlin/com/nylas/resources/Configurations.kt @@ -0,0 +1,114 @@ +package com.nylas.resources + +import com.nylas.NylasClient +import com.nylas.models.* +import com.nylas.util.JsonHelper + +/** + * Nylas Configurations API + * + * The Nylas configurations API allows you to create new configurations or manage existing ones, as well as getting + * configurations details for a user. + * + * Nylas Scheduler stores Configuration objects in the Scheduler database and loads + * them as Scheduling Pages in the Scheduler UI. + * + * @param client The configured Nylas API client + */ +class Configurations(client: NylasClient) : Resource<Configuration>(client, Configuration::class.java) { + + /** + * Return all Configurations + * @param identifier The identifier of the Grant to act upon. + * @param queryParams The query parameters to include in the request + * @param overrides Optional request overrides to apply + * @return The list of Configurations + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun list( + identifier: String, + queryParams: ListConfigurationsQueryParams? = null, + overrides: RequestOverrides? = null, + ): ListResponse<Configuration> { + val path = String.format("v3/grants/%s/scheduling/configurations", identifier) + return listResource(path, queryParams, overrides) + } + + /** + * Return a Configuration + * @param identifier The identifier of the Grant to act upon. + * @param configId The identifier of the Configuration to get. + * @param overrides Optional request overrides to apply + * @return The Configuration object + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun find( + identifier: String, + configId: String, + overrides: RequestOverrides? = null, + ): Response<Configuration> { + val path = String.format("v3/grants/%s/scheduling/configurations/%s", identifier, configId) + return findResource(path, overrides = overrides) + } + + /** + * Create a new Configuration + * @param identifier The identifier of the Grant to act upon. + * @param requestBody The data to create the Configuration with. + * @param overrides Optional request overrides to apply + * @return The Configuration object + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun create( + identifier: String, + requestBody: CreateConfigurationRequest, + overrides: RequestOverrides? = null, + ): Response<Configuration> { + val path = String.format("v3/grants/%s/scheduling/configurations", identifier) + val adapter = JsonHelper.moshi().adapter(CreateConfigurationRequest::class.java) + val serializedRequestBody = adapter.toJson(requestBody) + return createResource(path, serializedRequestBody, overrides = overrides) + } + + /** + * Update a Configuration + * @param identifier The identifier of the Grant to act upon. + * @param configId The identifier of the Configuration to update. + * @param requestBody The data to update the Configuration with. + * @param overrides Optional request overrides to apply + * @return The Configuration object + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun update( + identifier: String, + configId: String, + requestBody: UpdateConfigurationRequest, + overrides: RequestOverrides? = null, + ): Response<Configuration> { + val path = String.format("v3/grants/%s/scheduling/configurations/%s", identifier, configId) + val adapter = JsonHelper.moshi().adapter(UpdateConfigurationRequest::class.java) + val serializedRequestBody = adapter.toJson(requestBody) + return updateResource(path, serializedRequestBody, overrides = overrides) + } + + /** + * Delete a Configuration + * @param identifier The identifier of the Grant to act upon. + * @param configId The identifier of the Configuration to delete. + * @param overrides Optional request overrides to apply + * @return The deletion response + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + fun destroy( + identifier: String, + configId: String, + overrides: RequestOverrides? = null, + ): DeleteResponse { + val path = String.format("v3/grants/%s/scheduling/configurations/%s", identifier, configId) + return destroyResource(path, overrides = overrides) + } +} diff --git a/src/main/kotlin/com/nylas/resources/Scheduler.kt b/src/main/kotlin/com/nylas/resources/Scheduler.kt new file mode 100644 index 00000000..4388878f --- /dev/null +++ b/src/main/kotlin/com/nylas/resources/Scheduler.kt @@ -0,0 +1,34 @@ +package com.nylas.resources + +import com.nylas.NylasClient + +/** + * Nylas Scheduler API + * + * The Nylas Scheduler API allows you to manage scheduling configurations, bookings, and sessions. + * + * @param client The configured Nylas API client + */ +class Scheduler(private val client: NylasClient) { + + /** + * Access the Configurations API. + * + * @return The Configurations API. + */ + fun configurations(): Configurations = Configurations(client) + + /** + * Access the Sessions API. + * + * @return The Sessions API. + */ + fun sessions(): Sessions = Sessions(client) + + /** + * Access the Bookings API. + * + * @return The Bookings API. + */ + fun bookings(): Bookings = Bookings(client) +} diff --git a/src/main/kotlin/com/nylas/resources/Sessions.kt b/src/main/kotlin/com/nylas/resources/Sessions.kt new file mode 100644 index 00000000..2deea690 --- /dev/null +++ b/src/main/kotlin/com/nylas/resources/Sessions.kt @@ -0,0 +1,41 @@ +package com.nylas.resources + +import com.nylas.NylasClient +import com.nylas.models.* +import com.nylas.util.JsonHelper +/** + * Nylas Sessions API + * + * The Nylas Sessions API allows you to create and delete sessions on user Schedulerconfigurations. + * + * @param client The configured Nylas API client + */ +class Sessions(client: NylasClient) : Resource<Session>(client, Session::class.java) { + /** + * Create a Session + * @param requestBody The values to create the session with + * @param overrides Optional request overrides to apply + * @return The created session + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun create(requestBody: CreateSessionRequest, overrides: RequestOverrides? = null): Response<Session> { + val path = "v3/scheduling/sessions" + val adapter = JsonHelper.moshi().adapter(CreateSessionRequest::class.java) + val serializedRequestBody = adapter.toJson(requestBody) + return createResource(path, serializedRequestBody, overrides = overrides) + } + + /** + * Delete a Session + * @param sessionId The ID of the session to delete + * @param overrides Optional request overrides to apply + * @return The deleted response + */ + @Throws(NylasApiError::class, NylasSdkTimeoutError::class) + @JvmOverloads + fun destroy(sessionId: String, overrides: RequestOverrides? = null): DeleteResponse { + val path = String.format("v3/scheduling/sessions/%s", sessionId) + return destroyResource(path, overrides = overrides) + } +} diff --git a/src/test/kotlin/com/nylas/resources/BookingsTest.kt b/src/test/kotlin/com/nylas/resources/BookingsTest.kt new file mode 100644 index 00000000..137950e3 --- /dev/null +++ b/src/test/kotlin/com/nylas/resources/BookingsTest.kt @@ -0,0 +1,189 @@ +package com.nylas.resources + +import com.nylas.NylasClient +import com.nylas.models.* +import com.nylas.models.Response +import com.nylas.util.JsonHelper +import com.squareup.moshi.Types +import okhttp3.* +import okio.Buffer +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Nested +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.* +import java.lang.reflect.Type +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertIs + +class BookingsTest { + private val mockHttpClient: OkHttpClient = Mockito.mock(OkHttpClient::class.java) + private val mockCall: Call = Mockito.mock(Call::class.java) + private val mockResponse: okhttp3.Response = Mockito.mock(okhttp3.Response::class.java) + private val mockResponseBody: ResponseBody = Mockito.mock(ResponseBody::class.java) + private val mockOkHttpClientBuilder: OkHttpClient.Builder = Mockito.mock() + + @BeforeEach + fun setUp() { + MockitoAnnotations.openMocks(this) + whenever(mockOkHttpClientBuilder.addInterceptor(any())).thenReturn(mockOkHttpClientBuilder) + whenever(mockOkHttpClientBuilder.build()).thenReturn(mockHttpClient) + whenever(mockHttpClient.newCall(any())).thenReturn(mockCall) + whenever(mockCall.execute()).thenReturn(mockResponse) + whenever(mockResponse.isSuccessful).thenReturn(true) + whenever(mockResponse.body()).thenReturn(mockResponseBody) + } + + @Nested + inner class SerializationTests { + @Test + fun `Booking serializes properly`() { + val adapter = JsonHelper.moshi().adapter(Booking::class.java) + val jsonBuffer = Buffer().writeUtf8( + """ + { + "booking_id": "booking-123", + "event_id": "event-123", + "title": "My test event", + "organizer": { + "name": "John Doe", + "email": "user@example.com" + }, + "status": "booked", + "description": "This is an example of a description." + } + """.trimIndent(), + ) + + val booking = adapter.fromJson(jsonBuffer) + assertIs<Booking>(booking) + assertEquals("booking-123", booking.bookingId) + assertEquals("event-123", booking.eventId) + assertEquals("My test event", booking.title) + assertEquals("John Doe", booking.organizer.name) + assertEquals("user@example.com", booking.organizer.email) + assertEquals(BookingStatus.BOOKED, booking.status) + assertEquals("This is an example of a description.", booking.description) + } + } + + @Nested + inner class CrudTests { + private lateinit var mockNylasClient: NylasClient + private lateinit var bookings: Bookings + + @BeforeEach + fun setup() { + mockNylasClient = Mockito.mock(NylasClient::class.java) + bookings = Bookings(mockNylasClient) + } + + @Test + fun `creating a booking calls requests with the correct params`() { + val adapter = JsonHelper.moshi().adapter(CreateBookingRequest::class.java) + val participants = ArrayList<BookingParticipant>() + val bookingParticipant = BookingParticipant("test@nylas.com") + participants.add(bookingParticipant) + + val bookingGuest = BookingGuest("guest@nylas.com", "Guest") + val startTime = "1630000000" + val endTime = "1630003600" + + val createBookingRequest = CreateBookingRequest( + startTime = startTime, + endTime = endTime, + participants = participants, + guest = bookingGuest, + ) + + bookings.create(createBookingRequest) + + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val requestBodyCaptor = argumentCaptor<String>() + val queryParamCaptor = argumentCaptor<CreateBookingQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executePost<Booking>(pathCaptor.capture(), typeCaptor.capture(), requestBodyCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture()) + + assertEquals("v3/scheduling/bookings", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, Booking::class.java), typeCaptor.firstValue) + assertEquals(adapter.toJson(createBookingRequest), requestBodyCaptor.firstValue) + } + + @Test + fun `finding a booking calls requests with the correct params`() { + val bookingId = "booking-id" + bookings.find(bookingId) + + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val queryParamCaptor = argumentCaptor<FindBookingQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executeGet<Booking>(pathCaptor.capture(), typeCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture()) + + assertEquals("v3/scheduling/bookings/$bookingId", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, Booking::class.java), typeCaptor.firstValue) + } + + @Test + fun `rescheduling a booking calls requests with the correct params`() { + val adapter = JsonHelper.moshi().adapter(RescheduleBookingRequest::class.java) + val bookingId = "booking-id" + val rescheduleBookingRequest = RescheduleBookingRequest( + startTime = 1630000000, + endTime = 1630003600, + ) + bookings.reschedule(bookingId, rescheduleBookingRequest) + + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val requestBodyCaptor = argumentCaptor<String>() + val queryParamCaptor = argumentCaptor<RescheduleBookingQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executePatch<Booking>(pathCaptor.capture(), typeCaptor.capture(), requestBodyCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture()) + + assertEquals("v3/scheduling/bookings/$bookingId", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, Booking::class.java), typeCaptor.firstValue) + assertEquals(adapter.toJson(rescheduleBookingRequest), requestBodyCaptor.firstValue) + } + + @Test + fun `confirming a booking calls requests with the correct params`() { + val adapter = JsonHelper.moshi().adapter(ConfirmBookingRequest::class.java) + val bookingId = "booking-id" + val confirmBookingRequest = ConfirmBookingRequest( + salt = "salt123", + status = ConfirmBookingStatus.CANCELLED, + ) + + bookings.confirm(bookingId, confirmBookingRequest) + + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val requestBodyCaptor = argumentCaptor<String>() + val queryParamCaptor = argumentCaptor<ConfirmBookingQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executePut<Booking>(pathCaptor.capture(), typeCaptor.capture(), requestBodyCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture()) + + assertEquals("v3/scheduling/bookings/$bookingId", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, Booking::class.java), typeCaptor.firstValue) + assertEquals(adapter.toJson(confirmBookingRequest), requestBodyCaptor.firstValue) + } + + @Test + fun `destryoing a booking calls request with the correct params`() { + val bookingId = "booking-id" + bookings.destroy(bookingId) + + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val queryParamCaptor = argumentCaptor<DestroyBookingQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executeDelete<DeleteResponse>(pathCaptor.capture(), typeCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture()) + + assertEquals("v3/scheduling/bookings/$bookingId", pathCaptor.firstValue) + assertEquals(DeleteResponse::class.java, typeCaptor.firstValue) + } + } +} diff --git a/src/test/kotlin/com/nylas/resources/CalendarsTest.kt b/src/test/kotlin/com/nylas/resources/CalendarsTest.kt index 05d2d731..f9b88ea6 100644 --- a/src/test/kotlin/com/nylas/resources/CalendarsTest.kt +++ b/src/test/kotlin/com/nylas/resources/CalendarsTest.kt @@ -264,7 +264,7 @@ class CalendarsTest { exdates = listOf("2021-05-03", "2021-05-04"), ), ), - roundRobinEventId = "event-123", + roundRobinGroupId = "event-123", ), ) diff --git a/src/test/kotlin/com/nylas/resources/ConfigurationsTest.kt b/src/test/kotlin/com/nylas/resources/ConfigurationsTest.kt new file mode 100644 index 00000000..7fb5f34c --- /dev/null +++ b/src/test/kotlin/com/nylas/resources/ConfigurationsTest.kt @@ -0,0 +1,328 @@ +package com.nylas.resources + +import com.nylas.NylasClient +import com.nylas.models.* +import com.nylas.models.ListConfigurationsQueryParams +import com.nylas.models.Response +import com.nylas.util.JsonHelper +import com.squareup.moshi.Types +import okhttp3.* +import okio.Buffer +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Nested +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.* +import java.lang.reflect.Type +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertIs + +class ConfigurationsTest { + private val mockHttpClient: OkHttpClient = Mockito.mock(OkHttpClient::class.java) + private val mockCall: Call = Mockito.mock(Call::class.java) + private val mockResponse: okhttp3.Response = Mockito.mock(okhttp3.Response::class.java) + private val mockResponseBody: ResponseBody = Mockito.mock(ResponseBody::class.java) + private val mockOkHttpClientBuilder: OkHttpClient.Builder = Mockito.mock() + + @BeforeEach + fun setup() { + MockitoAnnotations.openMocks(this) + whenever(mockOkHttpClientBuilder.addInterceptor(any())).thenReturn(mockOkHttpClientBuilder) + whenever(mockOkHttpClientBuilder.build()).thenReturn(mockHttpClient) + whenever(mockHttpClient.newCall(any())).thenReturn(mockCall) + whenever(mockCall.execute()).thenReturn(mockResponse) + whenever(mockResponse.isSuccessful).thenReturn(true) + whenever(mockResponse.body()).thenReturn(mockResponseBody) + } + + @Nested + inner class SerializationTests { + @Test + fun `Configuration serializes properly`() { + val adapter = JsonHelper.moshi().adapter(Configuration::class.java) + val jsonBuffer = Buffer().writeUtf8( + """ + { + "id": "abc-123-configuration-id", + "slug": null, + "participants": [ + { + "email": "test@nylas.com", + "is_organizer": true, + "name": "Test", + "availability": { + "calendar_ids": [ + "primary" + ], + "open_hours": [ + { + "days": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6 + ], + "exdates": null, + "timezone": "", + "start": "09:00", + "end": "17:00" + } + ] + }, + "booking": { + "calendar_id": "primary" + }, + "timezone": "" + } + ], + "requires_session_auth": false, + "availability": { + "duration_minutes": 30, + "interval_minutes": 15, + "round_to": 15, + "availability_rules": { + "availability_method": "collective", + "buffer": { + "before": 60, + "after": 0 + }, + "default_open_hours": [ + { + "days": [ + 0, + 1, + 2, + 5, + 6 + ], + "exdates": null, + "timezone": "", + "start": "09:00", + "end": "18:00" + } + ], + "round_robin_group_id": "" + } + }, + "event_booking": { + "title": "Updated Title", + "timezone": "utc", + "description": "", + "location": null, + "booking_type": "booking", + "conferencing": { + "provider": "Microsoft Teams", + "autocreate": { + "conf_grant_id": "", + "conf_settings": null + } + }, + "hide_participants": null, + "disable_emails": null + }, + "scheduler": { + "available_days_in_future": 7, + "min_cancellation_notice": 60, + "min_booking_notice": 120, + "confirmation_redirect_url": "", + "hide_rescheduling_options": false, + "hide_cancellation_options": false, + "hide_additional_guests": true, + "cancellation_policy": "", + "email_template": { + "booking_confirmed": {} + } + }, + "appearance": { + "submit_button_label": "submit", + "thank_you_message": "thank you for your business. your booking was successful." + } + } + """.trimIndent(), + ) + + val config = adapter.fromJson(jsonBuffer)!! + assertIs<Configuration>(config) + assertEquals("abc-123-configuration-id", config.id) + assertEquals(false, config.requiresSessionAuth) + assertEquals(7, config.scheduler?.availableDaysInFuture) + assertEquals(60, config.scheduler?.minCancellationNotice) + assertEquals(120, config.scheduler?.minBookingNotice) + assertEquals("", config.scheduler?.confirmationRedirectUrl) + assertEquals(false, config.scheduler?.hideReschedulingOptions) + assertEquals(false, config.scheduler?.hideCancellationOptions) + assertEquals(true, config.scheduler?.hideAdditionalGuests) + assertEquals("", config.scheduler?.cancellationPolicy) + assertEquals("submit", config.appearance?.get("submit_button_label")) + assertEquals(30, config.availability.durationMinutes) + assertEquals(15, config.availability.intervalMinutes) + assertEquals(15, config.availability.roundTo) + assertEquals(AvailabilityMethod.COLLECTIVE, config.availability.availabilityRules?.availabilityMethod) + assertEquals(60, config.availability.availabilityRules?.buffer?.before) + assertEquals(0, config.availability.availabilityRules?.buffer?.after) + assertEquals("", config.availability.availabilityRules?.roundRobinGroupId) + assertEquals(5, config.availability.availabilityRules?.defaultOpenHours?.first()?.days?.size) + assertEquals("09:00", config.availability.availabilityRules?.defaultOpenHours?.first()?.start) + assertEquals("18:00", config.availability.availabilityRules?.defaultOpenHours?.first()?.end) + assertEquals("Updated Title", config.eventBooking.title) + assertEquals("utc", config.eventBooking.timezone) + assertEquals("", config.eventBooking.description) + assertEquals(null, config.eventBooking.location) + assertEquals(BookingType.BOOKING, config.eventBooking.bookingType) + assertEquals(null, config.eventBooking.hideParticipants) + assertEquals(null, config.eventBooking.disableEmails) + assertEquals(true, config.participants.first().isOrganizer) + assertEquals("test@nylas.com", config.participants.first().email) + assertEquals("Test", config.participants.first().name) + assertEquals("", config.participants.first().timezone) + } + } + + @Nested + inner class CrudTests { + private lateinit var grantId: String + private lateinit var mockNylasClient: NylasClient + private lateinit var configurations: Configurations + + @BeforeEach + fun setup() { + grantId = "abc-123-grant-id" + mockNylasClient = Mockito.mock(NylasClient::class.java) + configurations = Configurations(mockNylasClient) + } + + @Test + fun `listing configurations calls requests with the correct params`() { + configurations.list(grantId) + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val queryParamCaptor = argumentCaptor<ListConfigurationsQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executeGet<ListResponse<Configuration>>( + pathCaptor.capture(), + typeCaptor.capture(), + queryParamCaptor.capture(), + overrideParamCaptor.capture(), + ) + + assertEquals("v3/grants/$grantId/scheduling/configurations", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(ListResponse::class.java, Configuration::class.java), typeCaptor.firstValue) + } + + @Test + fun `creating a configuration calls requests with the correct params`() { + val adapter = JsonHelper.moshi().adapter(CreateConfigurationRequest::class.java) + val participantCalendarIds = ArrayList<String>() + participantCalendarIds.add("primary") + + val configurationAvailabilityParticipant = ConfigurationAvailabilityParticipant.Builder().calendarIds(participantCalendarIds).build() + + val configurationBookingParticipant = ConfigurationBookingParticipant.Builder().calendarId("primary").build() + + val configurationParticipant = ConfigurationParticipant.Builder("test@nylas.com") + .availability(configurationAvailabilityParticipant) + .booking(configurationBookingParticipant) + .name("Test Participant") + .isOrganizer(true) + .build() + + val configurationAvailability = ConfigurationAvailability.Builder().intervalMinutes(30).build() + + val configurationEventBooking = ConfigurationEventBooking.Builder().title("Test Event Booking").build() + + val participants = ArrayList<ConfigurationParticipant>() + participants.add(configurationParticipant) + + val createConfigurationRequest = CreateConfigurationRequest.Builder( + participants, + configurationAvailability, + configurationEventBooking, + ).build() + + configurations.create(grantId, createConfigurationRequest) + + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val requestBodyCaptor = argumentCaptor<String>() + val queryParamCaptor = argumentCaptor<ListConfigurationsQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executePost<Response<Configuration>>( + pathCaptor.capture(), + typeCaptor.capture(), + requestBodyCaptor.capture(), + queryParamCaptor.capture(), + overrideParamCaptor.capture(), + ) + assertEquals("v3/grants/$grantId/scheduling/configurations", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, Configuration::class.java), typeCaptor.firstValue) + assertEquals(adapter.toJson(createConfigurationRequest), requestBodyCaptor.firstValue) + } + + @Test + fun `updating a configuration calls requests with the correct params`() { + val adapter = JsonHelper.moshi().adapter(UpdateConfigurationRequest::class.java) + val configId = "abc-123-configuration-id" + val config = ConfigurationSchedulerSettings.Builder().minBookingNotice(120).build() + val updateConfigurationRequest = UpdateConfigurationRequest.Builder().scheduler(config).build() + + configurations.update(grantId, configId, updateConfigurationRequest) + + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val requestBodyCaptor = argumentCaptor<String>() + val queryParamCaptor = argumentCaptor<ListConfigurationsQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executePut<Response<Configuration>>( + pathCaptor.capture(), + typeCaptor.capture(), + requestBodyCaptor.capture(), + queryParamCaptor.capture(), + overrideParamCaptor.capture(), + ) + assertEquals("v3/grants/$grantId/scheduling/configurations/$configId", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, Configuration::class.java), typeCaptor.firstValue) + assertEquals(adapter.toJson(updateConfigurationRequest), requestBodyCaptor.firstValue) + } + + @Test + fun `finding a configuration calls requests with the correct params`() { + val configId = "configuration-id" + configurations.find(grantId, configId) + + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val queryParamCaptor = argumentCaptor<ListConfigurationsQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executeGet<Response<Configuration>>( + pathCaptor.capture(), + typeCaptor.capture(), + queryParamCaptor.capture(), + overrideParamCaptor.capture(), + ) + assertEquals("v3/grants/$grantId/scheduling/configurations/$configId", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, Configuration::class.java), typeCaptor.firstValue) + } + + @Test + fun `destroying a configuration calls requests with the correct params`() { + val configId = "configuration-id" + configurations.destroy(grantId, configId) + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val queryParamCaptor = argumentCaptor<ListConfigurationsQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executeDelete<DeleteResponse>( + pathCaptor.capture(), + typeCaptor.capture(), + queryParamCaptor.capture(), + overrideParamCaptor.capture(), + ) + assertEquals("v3/grants/$grantId/scheduling/configurations/$configId", pathCaptor.firstValue) + assertEquals(DeleteResponse::class.java, typeCaptor.firstValue) + } + } +} diff --git a/src/test/kotlin/com/nylas/resources/SessionsTest.kt b/src/test/kotlin/com/nylas/resources/SessionsTest.kt new file mode 100644 index 00000000..f4e7795c --- /dev/null +++ b/src/test/kotlin/com/nylas/resources/SessionsTest.kt @@ -0,0 +1,103 @@ +package com.nylas.resources + +import com.nylas.NylasClient +import com.nylas.models.* +import com.nylas.models.Response +import com.nylas.util.JsonHelper +import com.squareup.moshi.Types +import okhttp3.* +import okio.Buffer +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Nested +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import org.mockito.kotlin.* +import java.lang.reflect.Type +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertIs + +class SessionsTest { + private val mockHttpClient: OkHttpClient = Mockito.mock(OkHttpClient::class.java) + private val mockCall: Call = Mockito.mock(Call::class.java) + private val mockResponse: okhttp3.Response = Mockito.mock(okhttp3.Response::class.java) + private val mockResponseBody: ResponseBody = Mockito.mock(ResponseBody::class.java) + private val mockOkHttpClientBuilder: OkHttpClient.Builder = Mockito.mock() + + @BeforeEach + fun setup() { + MockitoAnnotations.openMocks(this) + whenever(mockOkHttpClientBuilder.addInterceptor(any())).thenReturn(mockOkHttpClientBuilder) + whenever(mockOkHttpClientBuilder.build()).thenReturn(mockHttpClient) + whenever(mockHttpClient.newCall(any())).thenReturn(mockCall) + whenever(mockCall.execute()).thenReturn(mockResponse) + whenever(mockResponse.isSuccessful).thenReturn(true) + whenever(mockResponse.body()).thenReturn(mockResponseBody) + } + + @Nested + inner class SerializationTests { + @Test + fun `Session serializes properly`() { + val adapter = JsonHelper.moshi().adapter(Session::class.java) + val jsonBuffer = Buffer().writeUtf8( + """ + { + "session_id": "session-id" + } + """.trimIndent(), + ) + val session = adapter.fromJson(jsonBuffer)!! + assertIs<Session>(session) + assertEquals("session-id", session.sessionId) + } + } + + @Nested + inner class CrudTests { + private lateinit var mockNylasClient: NylasClient + private lateinit var sessions: Sessions + + @BeforeEach + fun setup() { + mockNylasClient = Mockito.mock(NylasClient::class.java) + sessions = Sessions(mockNylasClient) + } + + @Test + fun `creating a session calls requests with the correct params`() { + val adapter = JsonHelper.moshi().adapter(CreateSessionRequest::class.java) + val createSessionRequest = CreateSessionRequest.Builder() + .configurationId("config-id") + .timeToLive(30) + .build() + + sessions.create(createSessionRequest) + + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val requestBodyCaptor = argumentCaptor<String>() + val queryParamCaptor = argumentCaptor<IQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executePost<Session>(pathCaptor.capture(), typeCaptor.capture(), requestBodyCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture()) + + assertEquals("v3/scheduling/sessions", pathCaptor.firstValue) + assertEquals(Types.newParameterizedType(Response::class.java, Session::class.java), typeCaptor.firstValue) + assertEquals(adapter.toJson(createSessionRequest), requestBodyCaptor.firstValue) + } + + @Test + fun `deleting a session calls requests with the correct params`() { + val sessionId = "session-id" + sessions.destroy(sessionId) + + val pathCaptor = argumentCaptor<String>() + val typeCaptor = argumentCaptor<Type>() + val queryParamCaptor = argumentCaptor<IQueryParams>() + val overrideParamCaptor = argumentCaptor<RequestOverrides>() + verify(mockNylasClient).executeDelete<DeleteResponse>(pathCaptor.capture(), typeCaptor.capture(), queryParamCaptor.capture(), overrideParamCaptor.capture()) + assertEquals("v3/scheduling/sessions/$sessionId", pathCaptor.firstValue) + assertEquals(DeleteResponse::class.java, typeCaptor.firstValue) + } + } +}