Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Nylas Java SDK Changelog

## [Unreleased]

### Changed
* `SendMessageRequest.sendAt` field changed from `Int?` to `Long?` to support Unix timestamps beyond 2038. Maintains backward compatibility through method overloading - existing `Int` parameters are automatically converted to `Long`. **Note:** Kotlin users passing integer literals may need to specify type explicitly (e.g., `1620000000L` or `1620000000 as Int`).

## [2.13.1]

### Fixed
Expand Down
13 changes: 10 additions & 3 deletions src/main/kotlin/com/nylas/models/SendMessageRequest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ data class SendMessageRequest(
* Unix timestamp to send the message at.
*/
@Json(name = "send_at")
val sendAt: Int? = null,
val sendAt: Long? = null,
/**
* The ID of the message that you are replying to.
*/
Expand Down Expand Up @@ -94,7 +94,7 @@ data class SendMessageRequest(
internal var subject: String? = null
private var body: String? = null
private var starred: Boolean? = null
private var sendAt: Int? = null
private var sendAt: Long? = null
private var replyToMessageId: String? = null
private var trackingOptions: TrackingOptions? = null
private var useDraft: Boolean? = null
Expand Down Expand Up @@ -162,7 +162,14 @@ data class SendMessageRequest(
* @param sendAt The unix timestamp to send the message at.
* @return The builder.
*/
fun sendAt(sendAt: Int?) = apply { this.sendAt = sendAt }
fun sendAt(sendAt: Long?) = apply { this.sendAt = sendAt }

/**
* Sets the unix timestamp to send the message at.
* @param sendAt The unix timestamp to send the message at (automatically converted to Long).
* @return The builder.
*/
fun sendAt(sendAt: Int?) = apply { this.sendAt = sendAt?.toLong() }

/**
* Sets the ID of the message that you are replying to.
Expand Down
69 changes: 69 additions & 0 deletions src/test/kotlin/com/nylas/resources/MessagesTests.kt
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,75 @@ class MessagesTests {
assertNull(queryParamCaptor.firstValue)
}

@Test
fun `sending a message with Int sendAt value calls requests with the correct params`() {
val adapter = JsonHelper.moshi().adapter(SendMessageRequest::class.java)
val sendMessageRequest =
SendMessageRequest.Builder(to = listOf(EmailName(email = "test@gmail.com", name = "Test")))
.body("Hello, I just sent a message using Nylas!")
.subject("Hello from Nylas!")
.sendAt(1620000000 as Int) // Explicitly test Int overload conversion to Long
.build()

messages.send(grantId, sendMessageRequest)

val pathCaptor = argumentCaptor<String>()
val typeCaptor = argumentCaptor<Type>()
val requestBodyCaptor = argumentCaptor<String>()
val queryParamCaptor = argumentCaptor<IQueryParams>()
val overrideParamCaptor = argumentCaptor<RequestOverrides>()
verify(mockNylasClient).executePost<Response<Message>>(
pathCaptor.capture(),
typeCaptor.capture(),
requestBodyCaptor.capture(),
queryParamCaptor.capture(),
overrideParamCaptor.capture(),
)

assertEquals("v3/grants/$grantId/messages/send", pathCaptor.firstValue)
assertEquals(Types.newParameterizedType(Response::class.java, Message::class.java), typeCaptor.firstValue)
assertEquals(adapter.toJson(sendMessageRequest), requestBodyCaptor.firstValue)
assertNull(queryParamCaptor.firstValue)

// Verify the sendAt field is properly set as Long
assertEquals(1620000000L, sendMessageRequest.sendAt)
}

@Test
fun `sending a message with Long sendAt value calls requests with the correct params`() {
val adapter = JsonHelper.moshi().adapter(SendMessageRequest::class.java)
val longTimestamp = 1893456000L // Year 2030 timestamp that exceeds Int.MAX_VALUE in the future
val sendMessageRequest =
SendMessageRequest.Builder(to = listOf(EmailName(email = "test@gmail.com", name = "Test")))
.body("Hello, I just sent a message using Nylas!")
.subject("Hello from Nylas!")
.sendAt(longTimestamp) // Long value
.build()

messages.send(grantId, sendMessageRequest)

val pathCaptor = argumentCaptor<String>()
val typeCaptor = argumentCaptor<Type>()
val requestBodyCaptor = argumentCaptor<String>()
val queryParamCaptor = argumentCaptor<IQueryParams>()
val overrideParamCaptor = argumentCaptor<RequestOverrides>()
verify(mockNylasClient).executePost<Response<Message>>(
pathCaptor.capture(),
typeCaptor.capture(),
requestBodyCaptor.capture(),
queryParamCaptor.capture(),
overrideParamCaptor.capture(),
)

assertEquals("v3/grants/$grantId/messages/send", pathCaptor.firstValue)
assertEquals(Types.newParameterizedType(Response::class.java, Message::class.java), typeCaptor.firstValue)
assertEquals(adapter.toJson(sendMessageRequest), requestBodyCaptor.firstValue)
assertNull(queryParamCaptor.firstValue)

// Verify the sendAt field is properly set as Long
assertEquals(longTimestamp, sendMessageRequest.sendAt)
}

@Test
fun `sending a message with a large attachment calls requests with the correct params`() {
val adapter = JsonHelper.moshi().adapter(SendMessageRequest::class.java)
Expand Down
Loading