Skip to content

Commit ce3598c

Browse files
ajay-kAaronDDM
andauthored
Added logo_url and show_nylas_branding options and ability to turn off Nylas branding (#283)
Added support for two missing fields (logo_url & showNylasBranding ) in the EmailTemplate class that were documented in the Scheduler API Reference but not implemented in the Java/Kotlin SDK. - Added proper JSON serialization with "Json" annotations ("logo", "show_nylas_branding") - Maintained backward compatibility - all new fields are optional - Included in Changelog # License <!-- Your PR comment must contain the following line for us to merge the PR. --> I confirm that this contribution is made under the terms of the MIT license and that I have the authority necessary to make this contribution on behalf of its copyright owner. --------- Co-authored-by: Aaron de Mello <[email protected]>
1 parent d47b137 commit ce3598c

File tree

3 files changed

+189
-1
lines changed

3 files changed

+189
-1
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Nylas Java SDK Changelog
22

33

4+
## [Unreleased]
5+
6+
### Added
7+
* Support for `logo` field in `EmailTemplate` class to specify a custom logo URL for booking emails
8+
* Support for `show_nylas_branding` field in `EmailTemplate` class to control Nylas branding visibility in booking emails
9+
410
## [2.10.0] - Release 2025-06-12
511

612
### Added

src/main/kotlin/com/nylas/models/ConfigurationSchedulerSettings.kt

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,61 @@ data class EmailTemplate(
262262
*/
263263
@Json(name = "booking_confirmed")
264264
val bookingConfirmed: BookingConfirmedTemplate? = null,
265-
)
265+
/**
266+
* URL of a custom logo to appear in booking emails.
267+
*/
268+
@Json(name = "logo")
269+
val logo: String? = null,
270+
/**
271+
* Boolean flag to toggle Nylas branding visibility.
272+
*/
273+
@Json(name = "show_nylas_branding")
274+
val showNylasBranding: Boolean? = null,
275+
) {
276+
/**
277+
* Builder for [EmailTemplate].
278+
*/
279+
class Builder {
280+
private var bookingConfirmed: BookingConfirmedTemplate? = null
281+
private var logo: String? = null
282+
private var showNylasBranding: Boolean? = null
283+
284+
/**
285+
* Set the configurable settings specifically for booking confirmed emails.
286+
*
287+
* @param bookingConfirmed Configurable settings specifically for booking confirmed emails.
288+
* @return The builder.
289+
*/
290+
fun bookingConfirmed(bookingConfirmed: BookingConfirmedTemplate) = apply { this.bookingConfirmed = bookingConfirmed }
291+
292+
/**
293+
* Set the URL of a custom logo to appear in booking emails.
294+
*
295+
* @param logo URL of a custom logo to appear in booking emails.
296+
* @return The builder.
297+
*/
298+
fun logo(logo: String) = apply { this.logo = logo }
299+
300+
/**
301+
* Set the boolean flag to toggle Nylas branding visibility.
302+
*
303+
* @param showNylasBranding Boolean flag to toggle Nylas branding visibility.
304+
* @return The builder.
305+
*/
306+
fun showNylasBranding(showNylasBranding: Boolean) = apply { this.showNylasBranding = showNylasBranding }
307+
308+
/**
309+
* Build the [EmailTemplate].
310+
*
311+
* @return The [EmailTemplate]
312+
*/
313+
fun build() = EmailTemplate(
314+
bookingConfirmed,
315+
logo,
316+
showNylasBranding,
317+
)
318+
}
319+
}
266320

267321
/**
268322
* Class representation of booking confirmed template settings.

src/test/kotlin/com/nylas/resources/ConfigurationsTest.kt

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,54 @@ class ConfigurationsTest {
182182
assertEquals("Test", config.participants.first().name)
183183
assertEquals("", config.participants.first().timezone)
184184
}
185+
186+
@Test
187+
fun `EmailTemplate with new fields serializes properly`() {
188+
val adapter = JsonHelper.moshi().adapter(EmailTemplate::class.java)
189+
val jsonBuffer = Buffer().writeUtf8(
190+
"""
191+
{
192+
"booking_confirmed": {
193+
"title": "Custom Booking Title",
194+
"body": "Thank you for booking with us!"
195+
},
196+
"logo": "https://example.com/logo.png",
197+
"show_nylas_branding": false
198+
}
199+
""".trimIndent(),
200+
)
201+
202+
val emailTemplate = adapter.fromJson(jsonBuffer)!!
203+
assertIs<EmailTemplate>(emailTemplate)
204+
assertEquals("https://example.com/logo.png", emailTemplate.logo)
205+
assertEquals(false, emailTemplate.showNylasBranding)
206+
assertEquals("Custom Booking Title", emailTemplate.bookingConfirmed?.title)
207+
assertEquals("Thank you for booking with us!", emailTemplate.bookingConfirmed?.body)
208+
209+
// Test serialization back to JSON
210+
val serializedJson = adapter.toJson(emailTemplate)
211+
assert(serializedJson.contains("\"logo\":\"https://example.com/logo.png\""))
212+
assert(serializedJson.contains("\"show_nylas_branding\":false"))
213+
}
214+
215+
@Test
216+
fun `EmailTemplate Builder works correctly`() {
217+
val bookingConfirmed = BookingConfirmedTemplate(
218+
title = "Custom Title",
219+
body = "Custom Body",
220+
)
221+
222+
val emailTemplate = EmailTemplate.Builder()
223+
.bookingConfirmed(bookingConfirmed)
224+
.logo("https://company.com/logo.svg")
225+
.showNylasBranding(true)
226+
.build()
227+
228+
assertEquals("https://company.com/logo.svg", emailTemplate.logo)
229+
assertEquals(true, emailTemplate.showNylasBranding)
230+
assertEquals("Custom Title", emailTemplate.bookingConfirmed?.title)
231+
assertEquals("Custom Body", emailTemplate.bookingConfirmed?.body)
232+
}
185233
}
186234

187235
@Nested
@@ -402,5 +450,85 @@ class ConfigurationsTest {
402450
assertEquals("v3/grants/$grantId/scheduling/configurations/$configId", pathCaptor.firstValue)
403451
assertEquals(DeleteResponse::class.java, typeCaptor.firstValue)
404452
}
453+
454+
@Test
455+
fun `creating a configuration with custom email template calls requests with the correct params`() {
456+
val adapter = JsonHelper.moshi().adapter(CreateConfigurationRequest::class.java)
457+
val participantCalendarIds = ArrayList<String>()
458+
participantCalendarIds.add("primary")
459+
460+
val configurationAvailabilityParticipant = ConfigurationAvailabilityParticipant.Builder().calendarIds(participantCalendarIds).build()
461+
462+
val configurationBookingParticipant = ConfigurationBookingParticipant.Builder().calendarId("primary").build()
463+
464+
val configurationParticipant = ConfigurationParticipant.Builder("[email protected]")
465+
.availability(configurationAvailabilityParticipant)
466+
.booking(configurationBookingParticipant)
467+
.name("Test Participant")
468+
.isOrganizer(true)
469+
.build()
470+
471+
val configurationAvailability = ConfigurationAvailability.Builder().intervalMinutes(30).build()
472+
473+
val configurationEventBooking = ConfigurationEventBooking.Builder().title("Test Event Booking").build()
474+
475+
// Create EmailTemplate with new logo and showNylasBranding fields
476+
val emailTemplate = EmailTemplate.Builder()
477+
.logo("https://company.com/custom-logo.png")
478+
.showNylasBranding(false)
479+
.bookingConfirmed(
480+
BookingConfirmedTemplate(
481+
title = "Your Meeting is Confirmed",
482+
body = "Thank you for booking! We look forward to meeting with you.",
483+
),
484+
)
485+
.build()
486+
487+
// Create scheduler settings with the email template
488+
val schedulerSettings = ConfigurationSchedulerSettings.Builder()
489+
.emailTemplate(emailTemplate)
490+
.availableDaysInFuture(14)
491+
.minBookingNotice(120)
492+
.build()
493+
494+
val participants = ArrayList<ConfigurationParticipant>()
495+
participants.add(configurationParticipant)
496+
497+
val createConfigurationRequest = CreateConfigurationRequest.Builder(
498+
participants,
499+
configurationAvailability,
500+
configurationEventBooking,
501+
)
502+
.name("Configuration with Custom Email Template")
503+
.scheduler(schedulerSettings)
504+
.build()
505+
506+
configurations.create(grantId, createConfigurationRequest)
507+
508+
val pathCaptor = argumentCaptor<String>()
509+
val typeCaptor = argumentCaptor<Type>()
510+
val requestBodyCaptor = argumentCaptor<String>()
511+
val queryParamCaptor = argumentCaptor<ListConfigurationsQueryParams>()
512+
val overrideParamCaptor = argumentCaptor<RequestOverrides>()
513+
verify(mockNylasClient).executePost<Response<Configuration>>(
514+
pathCaptor.capture(),
515+
typeCaptor.capture(),
516+
requestBodyCaptor.capture(),
517+
queryParamCaptor.capture(),
518+
overrideParamCaptor.capture(),
519+
)
520+
521+
assertEquals("v3/grants/$grantId/scheduling/configurations", pathCaptor.firstValue)
522+
assertEquals(Types.newParameterizedType(Response::class.java, Configuration::class.java), typeCaptor.firstValue)
523+
524+
val serializedRequest = adapter.toJson(createConfigurationRequest)
525+
assertEquals(serializedRequest, requestBodyCaptor.firstValue)
526+
527+
// Verify that the JSON contains the new EmailTemplate fields
528+
assert(serializedRequest.contains("\"logo\":\"https://company.com/custom-logo.png\""))
529+
assert(serializedRequest.contains("\"show_nylas_branding\":false"))
530+
assert(serializedRequest.contains("\"booking_confirmed\""))
531+
assert(serializedRequest.contains("Your Meeting is Confirmed"))
532+
}
405533
}
406534
}

0 commit comments

Comments
 (0)